| | |
| | | { |
| | | 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; |
| | |
| | | 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) |
| | | { |
| | |
| | | // Calculate parallax movement |
| | | Vector3 cameraDelta = cameraTransform.position - lastCameraPosition; |
| | | Vector3 newPosition = transform.position; |
| | | |
| | | |
| | | // Update X position with parallax |
| | | float parallaxX = (cameraTransform.position.x - startPositionX) * GetCurrentParallaxEffect(); |
| | |
| | | |
| | | 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() |
| | |
| | | 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; |
| | | } |
| | | } |
| | | } |