Quick Syntax
Mathf.Atan2(y, x)는 2D 방향의 사분면을 보존한 각도를 radian으로 돌려줍니다. Unity Inspector·Quaternion.Euler처럼 degree를 받는 API에는 Mathf.Rad2Deg를 곱하고, 359도와 1도 사이의 차이는 직접 나머지 연산을 만들지 말고 Mathf.DeltaAngle 또는 Mathf.MoveTowardsAngle로 처리합니다.
Vector2 delta = targetPosition - originPosition;
float targetDegrees = Mathf.Atan2(delta.y, delta.x) * Mathf.Rad2Deg;
// 스프라이트의 앞면이 +Y라면 +X 기준 각도에서 보정합니다.
float spriteDegrees = targetDegrees - 90f;
transform.rotation = Quaternion.Euler(0f, 0f, spriteDegrees);
// 현재 359도, 목표 1도처럼 경계를 넘어도 -180~180도의 짧은 차이를 반환합니다.
float shortestDegrees = Mathf.DeltaAngle(currentDegrees, targetDegrees);
float nextDegrees = Mathf.MoveTowardsAngle(
currentDegrees, targetDegrees, turnDegreesPerSecond * Time.deltaTime);| 필요한 결과 | 먼저 쓸 것 | 각도가 필요 없는 경우 |
|---|---|---|
| 2D 조준·아이콘 회전 | Atan2 후 degree·축 보정 | 없음, 화면에 각도를 표시해야 함 |
| 현재와 목표의 짧은 회전 차이 | DeltaAngle | 정면 여부만 판단할 때는 Vector3.Dot |
| 일정한 각속도 회전 | MoveTowardsAngle | 방향 벡터만 이동에 쓸 때는 정규화 |
방향 벡터를 각도로 바꾸기
두 위치를 빼면 origin에서 target을 향하는 방향 벡터가 됩니다. atan(y / x)는 x가 0인 경우와 사분면을 제대로 처리하지 못하므로 Atan2(y, x)를 사용합니다. Unity의 Mathf.Atan2와 다른 삼각함수는 radian을 사용합니다. Rad2Deg와 Deg2Rad를 변환 경계에 한 번만 두면 단위 혼용을 줄일 수 있습니다.
(+1, 0) -> 0도: +X, 오른쪽
( 0, +1) -> 90도: +Y, 위
(-1, 0) -> 180도: -X, 왼쪽
( 0, -1) -> -90도: -Y, 아래이 기준은 월드 XY 평면과 +X를 앞면으로 본 경우입니다. sprite 원본이 +Y를 향하거나 UI가 시계 방향 회전을 쓰면 offset·부호가 달라집니다. screen space에서는 Y축 방향과 world space의 Y축 방향도 다를 수 있으므로, 기준점·계산 공간·앞면 축을 코드 옆에 고정합니다.
경계 각도와 회전 방식
각도는 0도와 360도가 같은 방향이라는 점 때문에 일반 뺄셈만으로 회전량을 구하면 깨집니다. C#의 %는 음수 피연산자에 대해 수학적 modulo가 아니므로 ((difference + 180) % 360) - 180 같은 공식을 그대로 복사하면 음수 차이에서 긴 회전을 만들 수 있습니다. Unity에서는 Mathf.DeltaAngle(current, target)가 -179도부터 180도까지의 짧은 차이를 계산합니다.
Atan2는 목표 각도를 얻는 함수일 뿐 회전 감각을 정하지는 않습니다. 고정된 각속도는 MoveTowardsAngle, 정해진 duration은 start angle과 elapsed time으로 계산한 LerpAngle, 부드러운 추적은 SmoothDampAngle처럼 요구에 맞는 함수를 고릅니다. 3D rotation 전체를 다룰 때는 Z 각도 하나로 줄이지 말고 Quaternion.RotateTowards나 Quaternion.Slerp를 검토합니다.
각도 대신 벡터를 쓸 때
정면 판정, 좌우 판정, 이동 입력처럼 각도 숫자를 저장하거나 표시할 이유가 없다면 Atan2 -> degree -> sin/cos 왕복보다 벡터가 간단합니다. 두 방향의 가까움을 볼 때는 정규화한 뒤 Dot, 좌우 관계를 볼 때는 같은 평면을 전제로 Cross 부호를 사용합니다. 이때도 영벡터는 방향이 없으므로 target과 origin이 같은 경우를 먼저 처리합니다.
Atan2 결과의 단위와 기준축을 확인하지 않으면 계산은 맞아도 sprite·UI가 90도 또는 반대 방향을 봅니다. 긴 회전 문제는 Lerp 계수를 줄이는 문제가 아니라 각도 차이를 wrap하는 문제이므로 Unity에서는 DeltaAngle 계열을 우선 사용하세요.
참고 링크
2 sources