Quick Reference
위치 두 개를 빼면 거리와 방향을 가진 vector가 됩니다. 방향만 필요하면 magnitude를 확인한 뒤 정규화하고, 두 방향의 가까움은 Dot, 두 방향에 수직인 축이나 평면의 좌우는 Cross로 구합니다. Unity에서 너무 작은 vector를 정규화하면 NaN이 아니라 Vector3.zero가 반환되므로, 그 다음 방향 연산을 호출부가 처리해야 합니다.
Vector3 heading = target.position - transform.position;
if (heading.sqrMagnitude <= 0.000001f)
return; // target과 같은 위치에는 방향이 없습니다.
Vector3 toTarget = heading.normalized;
float facing = Vector3.Dot(transform.forward, toTarget);
bool isInFront = facing > 0f;
// Y-up 평면에서 forward(+Z)의 오른쪽(+X)을 만듭니다.
Vector3 right = Vector3.Cross(Vector3.up, transform.forward).normalized;
float side = Vector3.Cross(transform.forward, toTarget).y;| 필요한 판단 | 먼저 쓸 것 | 전제 |
|---|---|---|
| 거리·범위 | sqrMagnitude 또는 magnitude | 정규화하면 거리가 사라짐 |
| 시야·정면 | 정규화한 두 vector의 Dot | 같은 공간·같은 평면 기준 |
| 표면 normal·회전 축 | Cross(a, b) | 입력 순서가 방향을 결정 |
| 2D/지면 좌우 | 평면 normal 성분의 Cross | +Y-up 등 기준축을 고정 |
길이와 정규화
vector는 위치값에도 방향·속도·힘에도 쓰이는 container이므로, 값이 무엇을 뜻하는지 먼저 정합니다. target - current는 방향과 거리이고, normalized는 길이를 1로 만든 방향입니다. 방향 input을 정규화하면 diagonal 이동이 직선 이동보다 빨라지는 문제를 막을 수 있지만, knockback 세기나 거리 감쇠처럼 magnitude가 의미인 계산에서는 정규화하면 안 됩니다.
Unity Vector3.normalized와 static Vector3.Normalize는 원본을 바꾸지 않는 값을 반환하고, instance Normalize()는 현재 vector를 바꿉니다. 너무 작은 vector는 zero vector가 됩니다. zero를 Dot·Cross에 넣어도 exception은 나지 않지만 방향 판정이 의미 없으므로, sqrMagnitude로 먼저 검사하는 것이 target coincide와 정지 상태를 드러냅니다.
dot으로 방향 관계 읽기
두 vector가 unit vector이면 Dot(a, b)는 -1부터 1까지의 cosine 값입니다. 1은 같은 방향, 0은 수직, -1은 반대 방향입니다. 시야각의 절반 각도를 cosine으로 바꿔 threshold와 비교하면 acos로 각도를 매 frame 만들지 않아도 됩니다.
Vector3 forward = transform.forward;
Vector3 toTarget = (target.position - transform.position).normalized;
float halfFovDegrees = 30f;
bool isInFov = Vector3.Dot(forward, toTarget)
>= Mathf.Cos(halfFovDegrees * Mathf.Deg2Rad);높이가 시야 판정에 영향을 주면 3D vector를 그대로 쓰고, 지면에서만 판단할 때는 두 vector의 Y를 0으로 만든 뒤 다시 정규화합니다. 한쪽만 평면에 투영하면 서로 다른 공간의 길이·방향을 비교하게 됩니다.
cross의 순서와 평면
Vector3.Cross(a, b)는 a와 b에 수직인 vector를 만들고 입력 순서를 바꾸면 반대 방향이 됩니다. Unity 문서는 Cross 방향을 left-hand rule로 설명합니다. Y-up, forward +Z라는 Unity 관례에서 Vector3.Cross(Vector3.up, forward)는 right 방향을 만드는 표현이지만, custom coordinate 또는 다른 평면에서는 같은 이름의 식을 복사하지 말고 축을 확인합니다.
좌우 판정도 “어느 평면의 좌우인가”를 정해야 합니다. 지면 XZ 평면에서는 Cross(forward, toTarget).y의 부호를 사용하고, target이 forward의 오른쪽에 있는 known test scene에서 positive·negative가 어느 쪽인지 한 번 확인합니다. triangle normal은 vertex winding이 바뀌면 Cross 순서도 바뀌므로 culling·lighting 문제와 함께 확인합니다.
Unity에서 zero vector 정규화는 NaN이 아니라 zero를 돌려주지만, zero에는 방향이 없습니다. Dot·Cross의 숫자만 보고 이동·시야·좌우를 확정하지 말고, 먼저 길이와 평면·좌표축·입력 순서를 확인하세요.
참고 링크
2 sources