마우스를 클릭해서 그 위치까지 캐릭터를 이동시키고 나면, 캐릭터가 목표를 지나쳐서 멈추거나 혹은 다시 되돌아오는 현상을 한 번쯤은 경험해 보셨을 것입니다.
흔히 하는 실수
transform.position += direction * speed * Time.deltaTime;
if (Vector3.Distance(transform.position, targetPos) < 0.1f)
{
// 도착 처리
}
이처럼 먼저 움직이고 나서 도착 여부를 검사하는 구조는, 프레임당 이동 거리를 예측하지 못해 목표 지점을 쉽게 지나쳐버립니다. 결국 도착 판별은 따로 하고, 다시 위치를 조정하는 등의 간결하지 못한 코드가 되버립니다.
해결 방법 : 먼저 이동 위치를 예측하자
일단 이동부터 하고 나중에 도착 판별을 하는 구조가 아니라, 이동 전에 이동하려는 위치가 목표를 지나쳤는지 판단하는 방식으로 코드를 작성해야 합니다.
Vector3 direction = (targetPos - transform.position).normalized;
float distanceToTarget = Vector3.Distance(transform.position, targetPos);
float moveDistance = speed * Time.deltaTime;
if (moveDistance >= distanceToTarget)
{
// 현재 프레임에서 움직일 거리보다
// 목표 지점까지 남은 거리가 작거나 같다면,
// 물체를 목표 지점에 정확히 위치시킴
transform.position = targetPos;
}
else
{
// 이동해도 목표 지점에 도달하지 않는다면 이동.
transform.position += direction * moveDistance;
}
이 방식의 장점
• 목표 지점을 절대로 지나치지 않습니다.
• 예외 상황 (프레임 드랍 등) 에서도 안정적으로 작동합니다.
• 도착 판별과 위치 보정을 한 번에 처리합니다.
참고 : Unity 의 MoveTowards() 함수
Unity 에는 Vector3.MoveTowards() 라는 함수가 있으며, 내부적으로도 위와 같은 방식으로 예상 이동 위치와 목표 거리를 비교하여 지나치지 않도록 설계되어 있습니다.
따라서, 유니티라면 MoveTowards() 함수를 적극적으로 활용하는 것도 좋은 방법입니다.
'C#' 카테고리의 다른 글
Visual Studio 메뉴 폰트 크기 조정 (0) | 2025.07.01 |
---|---|
foreach() 순회 중 collection 변경은 예외 발생함 (0) | 2025.06.29 |
bool = 조건식 과 삼항 연산자 (0) | 2025.06.29 |
C# 의 Interface 기초부터 활용까지 (1) | 2025.06.26 |
C#의 is 와 as 키워드 (#02) (0) | 2025.06.26 |