From 90e3d4ae741a1bfbaca328ec8a4993be03084338 Mon Sep 17 00:00:00 2001 From: dal4segno Date: Thu, 2 Apr 2026 22:35:57 +0900 Subject: [PATCH] =?UTF-8?q?fix:=203=EC=9D=B8=EC=B9=AD=20=EC=B9=B4=EB=A9=94?= =?UTF-8?q?=EB=9D=BC=20=ED=8F=90=EC=83=89=20=EC=8B=9C=20=EC=88=9C=EA=B0=84?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=20=EB=B0=8F=20=EC=B6=A9=EB=8F=8C=20=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=20=EA=B3=BC=EB=8F=84=20=ED=8F=AC=ED=95=A8=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 카메라 충돌 시 SmoothDamp로 부드럽게 보간하도록 변경 (기존: 즉시 hit.point 이동) - collisionMask 기본값을 Default/Enemy/Ground 레이어로 제한 (기존: 모든 레이어 포함) - collisionRadius 0.2→0.3 증가로 보스 등 대형 오브젝트 탐지 개선 - minDistance 0.5 추가로 카메라가 플레이어 모델 안으로 파고드는 현상 방지 --- Assets/_Game/Scripts/Player/PlayerCamera.cs | 36 ++++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/Assets/_Game/Scripts/Player/PlayerCamera.cs b/Assets/_Game/Scripts/Player/PlayerCamera.cs index a06a3deb..fc025a3d 100644 --- a/Assets/_Game/Scripts/Player/PlayerCamera.cs +++ b/Assets/_Game/Scripts/Player/PlayerCamera.cs @@ -17,16 +17,22 @@ namespace Colosseum.Player [SerializeField] private float maxPitch = 60f; [Header("Collision")] - [SerializeField] private float collisionRadius = 0.2f; - [SerializeField] private LayerMask collisionMask = ~0; // 기본: 모든 레이어 + [SerializeField] private float collisionRadius = 0.3f; + [SerializeField] private LayerMask collisionMask; + [SerializeField] private float minDistance = 0.5f; [SerializeField] private float minHeightAboveGround = 0.3f; // 바닥 위 최소 카메라 높이 + [Header("Smooth Distance")] + [Min(0.01f)] [SerializeField] private float distanceSmoothTime = 0.15f; + private Transform target; private float yaw; private float pitch; private Camera cameraInstance; private InputSystem_Actions inputActions; private bool isSpectating = false; + private float currentDistance; + private float distanceSmoothVelocity; public Transform Target => target; public bool IsSpectating => isSpectating; @@ -56,6 +62,10 @@ namespace Colosseum.Player inputActions = actions; isSpectating = false; + // 충돌 마스크 기본값 설정 (Default, Enemy, Ground 레이어만) + if (collisionMask == 0) + collisionMask = LayerMask.GetMask("Default", "Enemy", "Ground"); + // 기존 메인 카메라 사용 또는 새로 생성 cameraInstance = Camera.main; Debug.Log($"[PlayerCamera] Initialize: target={playerTransform?.name}, Camera.main={cameraInstance?.name ?? "NULL"}"); @@ -73,6 +83,10 @@ namespace Colosseum.Player } pitch = 20f; + // 부드러운 거리 보간 상태 초기화 + currentDistance = distance; + distanceSmoothVelocity = 0f; + // 카메라 위치를 즉시 타겟 위치로 초기화 SnapToTarget(); } @@ -109,6 +123,10 @@ namespace Colosseum.Player { if (target == null || cameraInstance == null) return; + // 부드러운 거리 보간 상태 리셋 + currentDistance = distance; + distanceSmoothVelocity = 0f; + UpdateCameraPosition(); } @@ -162,12 +180,22 @@ namespace Colosseum.Player // pivot → desiredPos 방향으로 SphereCast해서 지형 충돌 감지 Vector3 dir = desiredPos - pivot; float maxDist = dir.magnitude; + float targetDistance = distance; if (Physics.SphereCast(pivot, collisionRadius, dir.normalized, out RaycastHit hit, maxDist, collisionMask, QueryTriggerInteraction.Ignore)) { - // 충돌 지점에서 collisionRadius만큼 pivot 쪽으로 당김 - desiredPos = hit.point + dir.normalized * collisionRadius; + // 충돌 지점에서 collisionRadius만큼 pivot 쪽으로 당긴 거리 + targetDistance = Mathf.Max(minDistance, hit.distance - collisionRadius); } + // 부드러운 거리 보간 + currentDistance = Mathf.SmoothDamp(currentDistance, targetDistance, ref distanceSmoothVelocity, distanceSmoothTime); + currentDistance = Mathf.Max(minDistance, currentDistance); + + // 보간된 거리로 최종 오프셋 재계산 + offset = rotation * new Vector3(0f, 0f, -currentDistance); + offset.y += height; + desiredPos = target.position + offset; + // 카메라 아래에 지면이 너무 가까우면 위로 밀어올려 바닥 아래면이 보이지 않게 함 if (Physics.Raycast(desiredPos, Vector3.down, out RaycastHit groundHit, minHeightAboveGround + 1f, collisionMask, QueryTriggerInteraction.Ignore)) {