using UnityEngine; namespace EerieVillage.Background { /// /// 무한 가로 스크롤 지면 collider — BoxCollider 재활용 reposition 패턴. /// PD 지시 (2026-05-10·결정 "(나) 형태로 진행해"): 맵 최하단 이동 가능 길·맵에 맞게 사이즈 자동. /// InfiniteHorizontalBackground 동일 패턴·BoxCollider 영역 적용. /// /// 동작: /// - Start: BoxCollider size.x 측정 + 자식 사본 2개 (Left·Right) BoxCollider 자동 생성. /// 자식 collider는 부모 Static Rb attachedRigidbody 자동 상속 (Unity 2D Physics 표준). /// - LateUpdate: Camera.x 영역 BoxCollider 폭 영역 정수 배수 root reposition. /// /// 효율: BoxCollider 1개 + 자식 2개 = 3개·Camera 영역 항상 collide 정합. /// [RequireComponent(typeof(BoxCollider2D))] public class InfiniteHorizontalGround : MonoBehaviour { Transform _camTr; float _colliderWidth; Transform _leftCopy; Transform _rightCopy; void Start() { var cam = Camera.main; if (cam == null) { Debug.LogWarning($"[InfiniteHorizontalGround@{name}] Camera.main NULL — disable."); enabled = false; return; } _camTr = cam.transform; var box = GetComponent(); // 월드 단위 BoxCollider 폭 (lossyScale 적용) _colliderWidth = box.size.x * transform.lossyScale.x; if (_colliderWidth <= 0.001f) { Debug.LogWarning($"[InfiniteHorizontalGround@{name}] colliderWidth ~0 — disable."); enabled = false; return; } // 자식 사본 2개 — Left·Right _leftCopy = CreateCopy("Left", -_colliderWidth, box); _rightCopy = CreateCopy("Right", +_colliderWidth, box); } Transform CreateCopy(string copyName, float worldOffsetX, BoxCollider2D src) { var copy = new GameObject(copyName); copy.transform.SetParent(transform, false); copy.layer = gameObject.layer; // localPosition은 parent.lossyScale 영향 — local 단위 변환 float localOffsetX = worldOffsetX / transform.lossyScale.x; copy.transform.localPosition = new Vector3(localOffsetX, 0f, 0f); copy.transform.localScale = Vector3.one; var box = copy.AddComponent(); box.size = src.size; box.offset = src.offset; box.isTrigger = src.isTrigger; box.sharedMaterial = src.sharedMaterial; return copy.transform; } void LateUpdate() { if (_camTr == null) return; float dx = _camTr.position.x - transform.position.x; if (Mathf.Abs(dx) >= _colliderWidth) { int n = Mathf.RoundToInt(dx / _colliderWidth); transform.position += new Vector3(n * _colliderWidth, 0f, 0f); } } } }