miepzerino
2025-04-05 ad8af928065a506d0d28f98d51222d7afa1f47e2
#47 background rework (static with transitions)
2 files modified
2 files added
252 ■■■■■ changed files
Assets/BackgroundManager.cs 121 ●●●●● patch | view | raw | blame | history
Assets/BackgroundManager.cs.meta 11 ●●●●● patch | view | raw | blame | history
Assets/Scenes/GameplayScene.unity 118 ●●●●● patch | view | raw | blame | history
Assets/Scripts/Managers/GameManager.cs 2 ●●● patch | view | raw | blame | history
Assets/BackgroundManager.cs
New file
@@ -0,0 +1,121 @@
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<SpriteRenderer>();
        // 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<SpriteRenderer>();
            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;
    }
}
Assets/BackgroundManager.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 718d5e9be0a4bd647adb3ea9fc7cf477
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Assets/Scenes/GameplayScene.unity
@@ -599,7 +599,7 @@
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
  m_AnchorMin: {x: 1, y: 1}
  m_AnchorMax: {x: 1, y: 1}
  m_AnchoredPosition: {x: 0.000061035156, y: 0}
  m_AnchoredPosition: {x: 0, y: 0}
  m_SizeDelta: {x: 200, y: 50}
  m_Pivot: {x: 1, y: 1}
--- !u!222 &456454179
@@ -1860,7 +1860,7 @@
  m_Icon: {fileID: 0}
  m_NavMeshLayer: 0
  m_StaticEditorFlags: 0
  m_IsActive: 0
  m_IsActive: 1
--- !u!4 &796676099
Transform:
  m_ObjectHideFlags: 0
@@ -1878,6 +1878,7 @@
  - {fileID: 1049982787}
  - {fileID: 2045670860}
  - {fileID: 734382261}
  - {fileID: 2136420133}
  m_Father: {fileID: 0}
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &808172310
@@ -4057,7 +4058,7 @@
  m_Name: 
  m_EditorClassIdentifier: 
  m_TrackedObjectOffset: {x: 0, y: 0, z: 0}
  m_LookaheadTime: 0.1
  m_LookaheadTime: 0
  m_LookaheadSmoothing: 5
  m_LookaheadIgnoreY: 0
  m_XDamping: 0
@@ -5215,6 +5216,113 @@
  hasTopBuddy: 0
  hasBottomBuddy: 0
  reverseScale: 1
--- !u!1 &2136420132
GameObject:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  serializedVersion: 6
  m_Component:
  - component: {fileID: 2136420133}
  - component: {fileID: 2136420135}
  - component: {fileID: 2136420134}
  m_Layer: 11
  m_Name: Background
  m_TagString: Untagged
  m_Icon: {fileID: 0}
  m_NavMeshLayer: 0
  m_StaticEditorFlags: 0
  m_IsActive: 1
--- !u!4 &2136420133
Transform:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 2136420132}
  serializedVersion: 2
  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
  m_LocalPosition: {x: 0, y: 0, z: -2}
  m_LocalScale: {x: 5, y: 5, z: 1}
  m_ConstrainProportionsScale: 0
  m_Children: []
  m_Father: {fileID: 796676099}
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &2136420134
SpriteRenderer:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 2136420132}
  m_Enabled: 1
  m_CastShadows: 0
  m_ReceiveShadows: 0
  m_DynamicOccludee: 1
  m_StaticShadowCaster: 0
  m_MotionVectors: 1
  m_LightProbeUsage: 1
  m_ReflectionProbeUsage: 1
  m_RayTracingMode: 0
  m_RayTraceProcedural: 0
  m_RenderingLayerMask: 1
  m_RendererPriority: 0
  m_Materials:
  - {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2}
  m_StaticBatchInfo:
    firstSubMesh: 0
    subMeshCount: 0
  m_StaticBatchRoot: {fileID: 0}
  m_ProbeAnchor: {fileID: 0}
  m_LightProbeVolumeOverride: {fileID: 0}
  m_ScaleInLightmap: 1
  m_ReceiveGI: 1
  m_PreserveUVs: 0
  m_IgnoreNormalsForChartDetection: 0
  m_ImportantGI: 0
  m_StitchLightmapSeams: 1
  m_SelectedEditorRenderState: 0
  m_MinimumChartSize: 4
  m_AutoUVMaxDistance: 0.5
  m_AutoUVMaxAngle: 89
  m_LightmapParameters: {fileID: 0}
  m_SortingLayerID: 1963190711
  m_SortingLayer: -2
  m_SortingOrder: 0
  m_Sprite: {fileID: 0}
  m_Color: {r: 1, g: 1, b: 1, a: 1}
  m_FlipX: 0
  m_FlipY: 0
  m_DrawMode: 0
  m_Size: {x: 1, y: 1}
  m_AdaptiveModeThreshold: 0.5
  m_SpriteTileMode: 0
  m_WasSpriteAssigned: 0
  m_MaskInteraction: 0
  m_SpriteSortPoint: 0
--- !u!114 &2136420135
MonoBehaviour:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 2136420132}
  m_Enabled: 1
  m_EditorHideFlags: 0
  m_Script: {fileID: 11500000, guid: 718d5e9be0a4bd647adb3ea9fc7cf477, type: 3}
  m_Name:
  m_EditorClassIdentifier:
  spriteRenderer: {fileID: 2136420134}
  transitionRenderer: {fileID: 0}
  backgroundLayers:
  - yThreshold: -1
    backgroundSprite: {fileID: 21300000, guid: 7d5be99b0261348468ab492c35422f1b, type: 3}
    parallaxEffect: 0.439
  - yThreshold: -300
    backgroundSprite: {fileID: 21300000, guid: 58a6eeb45a0e2674ab35114433129f28, type: 3}
    parallaxEffect: 0.482
  transitionDuration: 1
--- !u!114 &18669457987763773
MonoBehaviour:
  m_ObjectHideFlags: 0
@@ -13157,6 +13265,10 @@
      propertyPath: m_Name
      value: BackgroundAll
      objectReference: {fileID: 0}
    - target: {fileID: 3961525155789603524, guid: bcc4a9d71ad64b340b222e078e04fe7c, type: 3}
      propertyPath: m_IsActive
      value: 0
      objectReference: {fileID: 0}
    - target: {fileID: 6632530311481836413, guid: bcc4a9d71ad64b340b222e078e04fe7c, type: 3}
      propertyPath: m_LocalPosition.x
      value: 0
Assets/Scripts/Managers/GameManager.cs
@@ -92,7 +92,7 @@
        Debug.Log("done async map loading");
        levelChanger.GetComponent<Animator>().SetBool("SceneLoading", false);
        //Initialize background tiles after the tilemap is loaded
        InitializeBackgroundTiles();
        //InitializeBackgroundTiles();
        GameLoaded();
    }
    public void GameLoaded()