EerieVillage/Assets/Scripts/Background/CameraBackgroundLimit.cs

73 lines
2.7 KiB
C#

using UnityEngine;
using Unity.Cinemachine;
namespace EerieVillage.Background
{
/// <summary>
/// CinemachineConfiner2D 의 BoundingShape (PolygonCollider2D) 를 배경 SpriteRenderer bounds 정합으로 동적 갱신.
/// Camera ortho size · screen aspect 변경 시 자동 정합 — 해상도 동적 처리.
///
/// PD 지시 (2026-05-12):
/// - 점프 후 카메라 원래 위치 복귀
/// - 카메라가 배경 이미지 벗어나는 지점 표시 X
/// - 해상도 고려 동적 판단
///
/// 동작:
/// - Update / LateUpdate (Editor·Runtime 동시 호출): 배경 bounds 와 boundShape 의 transform offset 기준으로 PolygonCollider2D points 4개를 단순 사각형으로 갱신.
/// - 배경 bounds 또는 boundShape offset 변경 감지 시에만 SetPath + Confiner.InvalidateBoundingShapeCache.
/// - Confiner 자체가 Camera ortho · aspect 를 알아서 카메라 보이는 영역이 polygon 안에 머물도록 강제.
/// </summary>
[ExecuteAlways]
public class CameraBackgroundLimit : MonoBehaviour
{
[Tooltip("배경 SpriteRenderer — bounds 가 카메라 한계 기준")]
public SpriteRenderer backgroundSprite;
[Tooltip("Confiner BoundingShape — PolygonCollider2D")]
public PolygonCollider2D boundShape;
[Tooltip("CinemachineConfiner2D — InvalidateBoundingShapeCache 호출 대상")]
public CinemachineConfiner2D confiner;
Vector3 _lastMin;
Vector3 _lastMax;
Vector3 _lastShapePos;
void Update()
{
UpdateShape();
}
void LateUpdate()
{
UpdateShape();
}
void UpdateShape()
{
if (backgroundSprite == null || boundShape == null) return;
var bg = backgroundSprite.bounds;
var shapePos = boundShape.transform.position;
if (bg.min == _lastMin && bg.max == _lastMax && shapePos == _lastShapePos) return;
_lastMin = bg.min;
_lastMax = bg.max;
_lastShapePos = shapePos;
// Polygon points 를 배경 bounds 정합 직사각형으로 갱신 (local space = world - shape.position)
float minX = bg.min.x - shapePos.x;
float maxX = bg.max.x - shapePos.x;
float minY = bg.min.y - shapePos.y;
float maxY = bg.max.y - shapePos.y;
var pts = new Vector2[]
{
new Vector2(maxX, maxY),
new Vector2(minX, maxY),
new Vector2(minX, minY),
new Vector2(maxX, minY)
};
boundShape.SetPath(0, pts);
if (confiner != null) confiner.InvalidateBoundingShapeCache();
}
}
}