using UnityEngine;
/// <summary>
/// GAME 1303 Tier 1 — Background layers that scroll slower than the camera for depth.
///
/// SETUP
/// 1. For each background layer, make a GameObject with a SpriteRenderer.
/// Sort them with Order in Layer (far = lowest) or a "Background" sorting layer.
/// 2. Add this script to each layer. Set Depth:
/// 0.0 = glued to camera (sky, never moves on screen)
/// 0.3 = distant mountains 0.6 = mid trees
/// 0.9 = near bushes 1.0 = part of the world (no parallax)
/// 3. Infinite Repeat: ON for layers that should tile forever sideways. On Start the
/// script spawns a copy on each side; the sprite must be seamless left-to-right.
/// 4. Works with Cinemachine: we read Camera.main's position each LateUpdate, and
/// Cinemachine has already moved the camera by then.
/// </summary>
[RequireComponent(typeof(SpriteRenderer))]
public class ParallaxBackground : MonoBehaviour
{
[Tooltip("0 = moves with camera (far away). 1 = stays in world (no parallax).")]
[Range(0f, 1f)] public float depth = 0.5f;
[Tooltip("Vertical parallax strength. Usually weaker than horizontal.")]
[Range(0f, 1f)] public float verticalDepth = 0.8f;
public bool infiniteRepeat = true;
private Transform cam;
private Vector3 lastCamPos;
private float tileWidth;
void Start()
{
cam = Camera.main.transform;
lastCamPos = cam.position;
var sr = GetComponent<SpriteRenderer>();
tileWidth = sr.bounds.size.x;
if (infiniteRepeat && tileWidth > 0f)
{
// Spawn a plain copy on each side (no script on the copies)
for (int i = -1; i <= 1; i += 2)
{
GameObject copy = new GameObject(name + "_tile");
copy.transform.SetParent(transform, false);
copy.transform.localPosition = new Vector3(i * tileWidth / transform.lossyScale.x, 0f, 0f);
var csr = copy.AddComponent<SpriteRenderer>();
csr.sprite = sr.sprite;
csr.sortingLayerID = sr.sortingLayerID;
csr.sortingOrder = sr.sortingOrder;
csr.color = sr.color;
}
}
}
void LateUpdate()
{
Vector3 delta = cam.position - lastCamPos;
// The layer follows the camera by (1 - depth). depth 0 => follows fully (appears static).
transform.position += new Vector3(delta.x * (1f - depth), delta.y * (1f - verticalDepth), 0f);
lastCamPos = cam.position;
// Snap by a full tile when the camera drifts past one tile width, so the three
// tiles always surround the camera.
if (infiniteRepeat && tileWidth > 0f)
{
float offset = cam.position.x - transform.position.x;
if (offset > tileWidth) transform.position += Vector3.right * tileWidth;
else if (offset < -tileWidth) transform.position -= Vector3.right * tileWidth;
}
}
}