miepzerino
2025-04-05 575af36b9ec3d3c39ffb027c13c5a9bd0b369f97
#47 background transition based on y-level
2 files modified
93 ■■■■ changed files
Assets/BackgroundManager.cs 87 ●●●● patch | view | raw | blame | history
Assets/Scenes/GameplayScene.unity 6 ●●●●● patch | view | raw | blame | history
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,27 +128,51 @@
        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;
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