From 575af36b9ec3d3c39ffb027c13c5a9bd0b369f97 Mon Sep 17 00:00:00 2001 From: miepzerino <o.skotnik@gmail.com> Date: Sat, 05 Apr 2025 17:44:41 +0000 Subject: [PATCH] #47 background transition based on y-level --- Assets/BackgroundManager.cs | 91 +++++++++++++++++++++++++++++++++++++-------- 1 files changed, 75 insertions(+), 16 deletions(-) diff --git a/Assets/BackgroundManager.cs b/Assets/BackgroundManager.cs index 7679293..2722ba7 100644 --- a/Assets/BackgroundManager.cs +++ b/Assets/BackgroundManager.cs @@ -9,13 +9,14 @@ { public float yThreshold; public Sprite backgroundSprite; + public float transitionDistance = 3f; // Distance over which the transition occurs [Range(0f, 1f)] public float parallaxEffect = 0.5f; } [SerializeField] private SpriteRenderer spriteRenderer; [SerializeField] private SpriteRenderer transitionRenderer; // Add this field [SerializeField] private BackgroundLayer[] backgroundLayers; - [SerializeField] private float transitionDuration = 1f; + [SerializeField] private Transform playerTransform; // Add this field private bool isTransitioning = false; // Add this field private Transform cameraTransform; @@ -23,18 +24,36 @@ private int currentLayerIndex = 0; private float startPositionX; + private float lastUpdatePlayerY = 0f; // Track the last Y position of the player + private bool isMovingUp = false; // Track if the player is moving up + private void Start() { cameraTransform = Camera.main.transform; lastCameraPosition = cameraTransform.position; - startPositionX = transform.position.x; - + if (spriteRenderer == null) spriteRenderer = GetComponent<SpriteRenderer>(); - // Set initial background + // Set initial background based on player position if (backgroundLayers != null && backgroundLayers.Length > 0) - spriteRenderer.sprite = backgroundLayers[0].backgroundSprite; + { + float playerY = playerTransform.position.y; + int initialLayerIndex = 0; + + // Find the correct background layer for the player's position + for (int i = 0; i < backgroundLayers.Length; i++) + { + if (playerY > backgroundLayers[i].yThreshold) + { + initialLayerIndex = i; + break; + } + } + + spriteRenderer.sprite = backgroundLayers[initialLayerIndex].backgroundSprite; + currentLayerIndex = initialLayerIndex; + } if (transitionRenderer == null) { @@ -54,6 +73,7 @@ // Calculate parallax movement Vector3 cameraDelta = cameraTransform.position - lastCameraPosition; Vector3 newPosition = transform.position; + // Update X position with parallax float parallaxX = (cameraTransform.position.x - startPositionX) * GetCurrentParallaxEffect(); @@ -79,11 +99,26 @@ if (newLayerIndex != currentLayerIndex && !isTransitioning) // Add transition check { - StartCoroutine(TransitionBackground(backgroundLayers[newLayerIndex].backgroundSprite)); + StartCoroutine(TransitionBackground(backgroundLayers[newLayerIndex])); currentLayerIndex = newLayerIndex; } lastCameraPosition = cameraTransform.position; + float lastUpdatePlayerYRounded = Mathf.Round(lastUpdatePlayerY * 10) / 10; + float playerYRounded = Mathf.Round(playerTransform.position.y * 10) / 10; + if (lastUpdatePlayerYRounded != playerYRounded) // Check if player has moved + { + if (lastUpdatePlayerYRounded > playerYRounded) // Check if player is moving down + { + isMovingUp = false; + } + else if (lastUpdatePlayerYRounded < playerYRounded) // Check if player is moving up + { + isMovingUp = true; + } + lastUpdatePlayerY = playerYRounded; // Update the last Y position + } + } private float GetCurrentParallaxEffect() @@ -93,29 +128,53 @@ return backgroundLayers[currentLayerIndex].parallaxEffect; } - private IEnumerator TransitionBackground(Sprite newSprite) + private IEnumerator TransitionBackground(BackgroundLayer newLayer) { - if (isTransitioning) yield break; + // Check if the transition is already in progress or if the new sprite is the same as the current one + if (isTransitioning || newLayer.backgroundSprite.name == spriteRenderer.sprite.name) yield break; isTransitioning = true; // Setup transition renderer - transitionRenderer.sprite = newSprite; + transitionRenderer.sprite = newLayer.backgroundSprite; transitionRenderer.transform.localPosition = Vector3.zero; + bool initialMovingUp = isMovingUp; // Store the initial moving direction + float initialY = playerTransform.position.y; + //bool movingUp = playerTransform.position.y > initialY; + // Fade in new sprite over old one - float elapsedTime = 0; - while (elapsedTime < transitionDuration) + while (true) { - elapsedTime += Time.deltaTime; - float alpha = elapsedTime / transitionDuration; - transitionRenderer.color = new Color(1, 1, 1, alpha); + float currentY = playerTransform.position.y; + + // Check if the direction has changed + if (initialMovingUp != isMovingUp && + ((initialMovingUp ? initialY > currentY : initialY < currentY) + )) + { + transitionRenderer.color = new Color(1, 1, 1, 0); + isTransitioning = false; + yield break; + } + + // Calculate the alpha based on the distance moved + float alpha = Mathf.Abs(currentY - initialY) / newLayer.transitionDistance; + transitionRenderer.color = new Color(1, 1, 1, Mathf.Clamp01(alpha)); + + // Check if transition is complete + if (alpha >= 1f) + break; + yield return null; } + // Ensure the final alpha value is set correctly + transitionRenderer.color = new Color(1, 1, 1, 1); + // Switch the sprites - spriteRenderer.sprite = newSprite; + spriteRenderer.sprite = newLayer.backgroundSprite; transitionRenderer.color = new Color(1, 1, 1, 0); isTransitioning = false; } -} \ No newline at end of file +} -- Gitblit v1.9.3