using System.Collections; using System.Collections.Generic; using UnityEngine; public class BackgroundManager : MonoBehaviour { [System.Serializable] public class BackgroundLayer { public float yThreshold; public Sprite backgroundSprite; [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; private bool isTransitioning = false; // Add this field private Transform cameraTransform; private Vector3 lastCameraPosition; private int currentLayerIndex = 0; private float startPositionX; private void Start() { cameraTransform = Camera.main.transform; lastCameraPosition = cameraTransform.position; startPositionX = transform.position.x; if (spriteRenderer == null) spriteRenderer = GetComponent(); // Set initial background if (backgroundLayers != null && backgroundLayers.Length > 0) spriteRenderer.sprite = backgroundLayers[0].backgroundSprite; if (transitionRenderer == null) { var transitionObj = new GameObject("TransitionLayer"); transitionObj.transform.parent = transform; transitionObj.transform.localPosition = new Vector3(0, 0, -2); // Set Z to -2 transitionObj.transform.localScale = Vector3.one; // Match scale transitionRenderer = transitionObj.AddComponent(); transitionRenderer.sortingOrder = spriteRenderer.sortingOrder + 1; transitionRenderer.sortingLayerName = spriteRenderer.sortingLayerName; // Match background layer } transitionRenderer.color = new Color(1, 1, 1, 0); // Start fully transparent } private void Update() { // Calculate parallax movement Vector3 cameraDelta = cameraTransform.position - lastCameraPosition; Vector3 newPosition = transform.position; // Update X position with parallax float parallaxX = (cameraTransform.position.x - startPositionX) * GetCurrentParallaxEffect(); newPosition.x = startPositionX + parallaxX; // Update Y position to follow camera newPosition.y = cameraTransform.position.y; transform.position = newPosition; // Check for background change float currentY = cameraTransform.position.y; int newLayerIndex = currentLayerIndex; for (int i = 0; i < backgroundLayers.Length; i++) { if (currentY > backgroundLayers[i].yThreshold) { newLayerIndex = i; break; } } if (newLayerIndex != currentLayerIndex && !isTransitioning) // Add transition check { StartCoroutine(TransitionBackground(backgroundLayers[newLayerIndex].backgroundSprite)); currentLayerIndex = newLayerIndex; } lastCameraPosition = cameraTransform.position; } private float GetCurrentParallaxEffect() { if (backgroundLayers == null || backgroundLayers.Length == 0) return 0.5f; return backgroundLayers[currentLayerIndex].parallaxEffect; } private IEnumerator TransitionBackground(Sprite newSprite) { if (isTransitioning) yield break; isTransitioning = true; // Setup transition renderer transitionRenderer.sprite = newSprite; transitionRenderer.transform.localPosition = Vector3.zero; // Fade in new sprite over old one float elapsedTime = 0; while (elapsedTime < transitionDuration) { elapsedTime += Time.deltaTime; float alpha = elapsedTime / transitionDuration; transitionRenderer.color = new Color(1, 1, 1, alpha); yield return null; } // Switch the sprites spriteRenderer.sprite = newSprite; transitionRenderer.color = new Color(1, 1, 1, 0); isTransitioning = false; } }