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/Scenes/GameplayScene.unity |    6 ++-
 Assets/BackgroundManager.cs       |   91 +++++++++++++++++++++++++++++++++++++--------
 2 files changed, 79 insertions(+), 18 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
+}
diff --git a/Assets/Scenes/GameplayScene.unity b/Assets/Scenes/GameplayScene.unity
index 5b06c17..88982ad 100644
--- a/Assets/Scenes/GameplayScene.unity
+++ b/Assets/Scenes/GameplayScene.unity
@@ -5316,13 +5316,15 @@
   spriteRenderer: {fileID: 2136420134}
   transitionRenderer: {fileID: 0}
   backgroundLayers:
-  - yThreshold: -1
+  - yThreshold: -5
     backgroundSprite: {fileID: 21300000, guid: 7d5be99b0261348468ab492c35422f1b, type: 3}
+    transitionDistance: 4
     parallaxEffect: 0.439
   - yThreshold: -300
     backgroundSprite: {fileID: 21300000, guid: 58a6eeb45a0e2674ab35114433129f28, type: 3}
+    transitionDistance: 5
     parallaxEffect: 0.482
-  transitionDuration: 1
+  playerTransform: {fileID: 254538002}
 --- !u!114 &18669457987763773
 MonoBehaviour:
   m_ObjectHideFlags: 0

--
Gitblit v1.9.3