오늘은 충돌 감지에 사용되는 AABB와 OBB에 대해서 알아보고 Unit Collider에 어떻게 적용되는지에 대해 알아보겠습니다.

➡️ AABB (Axis - Aligned Bounding Box)는 이름에서 알 수 있듯이 상자의 모든 면이 전역 좌표계의 x,y,z 축과 평행하도록 정의됩니다.
장점
- 두 AABB 간의 충돌 여부는 각 축에 대해 최소/최대 값의 범위가 겹치는지만 확인하므로 계산이 굉장히 빠릅니다.
- 많은 객체들이 있을 때 빠르게 후보 충돌 쌍을 거르기 위해 널리 사용됩니다.
단점
- 객체가 회전하거나 비정형인 경우 AABB는 실제 객체보다 훨씬 큰 영역을 감싸게 되어 불필요한 충돌 검사가 발생할 수 있습니다.
- 객체의 로컬 형태와 실제 월드 공간에서의 모양이 달라질 수 있습니다.
if (col != null)
{
Gizmos.color = Color.blue;
Bounds aabb = col.bounds;
Gizmos.DrawWireCube(aabb.center, aabb.size);
}
- Unity의 Collider.bouns는 월드 좌표계에서 축에 정렬된 경계 상자를 반환합니다.
➡️ OBB (Oriented Bounding Box)는 객체의 회전 상태나 기하학적 형태를 반영하여 상자가 객체에 맞게 회전된 형태로 정의됩니다.
장점
- 회전하는 객체에 대해 실제 모양에 근접하는 경계체를 제공하여 불필요한 충돌 검사를 줄입니다.
단점
- 두 OBB 사이의 충돌 검사는 복잡한 알고리즘을 사용해야 하므로 연산 비용이 높습니다.
- 객체의 변환이 있을 때마다 경곛체를 갱신해야 하므로 관리가 복잡할 수 있습니다.
if (box != null)
{
Gizmos.color = Color.red;
Vector3[] corners = GetBoxColliderCorners(box);
// 12개의 엣지를 그려서 OBB를 시각화
// 바닥 면 (0, 1, 2, 3)
DrawLine(corners[0], corners[1]);
DrawLine(corners[1], corners[2]);
DrawLine(corners[2], corners[3]);
DrawLine(corners[3], corners[0]);
// 윗면 (4, 5, 6, 7)
DrawLine(corners[4], corners[5]);
DrawLine(corners[5], corners[6]);
DrawLine(corners[6], corners[7]);
DrawLine(corners[7], corners[4]);
// 수직 엣지
DrawLine(corners[0], corners[4]);
DrawLine(corners[1], corners[5]);
DrawLine(corners[2], corners[6]);
DrawLine(corners[3], corners[7]);
}
// BoxCollider의 로컬 코너를 월드 공간으로 변환하여 OBB의 8개 코너를 반환합니다.
Vector3[] GetBoxColliderCorners(BoxCollider boxCollider)
{
Vector3[] corners = new Vector3[8];
// BoxCollider의 로컬 중심과 크기를 가져옴
Vector3 center = boxCollider.center;
Vector3 size = boxCollider.size;
Vector3 half = size * 0.5f;
// 로컬 공간에서 8개의 코너 계산
corners[0] = center + new Vector3(-half.x, -half.y, -half.z);
corners[1] = center + new Vector3(half.x, -half.y, -half.z);
corners[2] = center + new Vector3(half.x, -half.y, half.z);
corners[3] = center + new Vector3(-half.x, -half.y, half.z);
corners[4] = center + new Vector3(-half.x, half.y, -half.z);
corners[5] = center + new Vector3(half.x, half.y, -half.z);
corners[6] = center + new Vector3(half.x, half.y, half.z);
corners[7] = center + new Vector3(-half.x, half.y, half.z);
// 각 코너를 GameObject의 월드 좌표로 변환
for (int i = 0; i < corners.Length; i++)
{
corners[i] = boxCollider.transform.TransformPoint(corners[i]);
}
return corners;
}
- BoxCollider는 로컬 공간에서 center와 size로 정의됩니다.
- GetBoxColliderCorners() 함수를 통해 로컬 공간에서의 8개의 코너를 계산한 후 TransformPoint를 통해 월드 공간의 좌표로 반환합니다.

➡️ 파란색 : AABB
➡️ 빨간색 : OBB
- 회전을 할 때 AABB의 경우 단점에서 언급한 것 처럼 실제보다 큰 영역을 감싸는 모습을 확인할 수 있습니다.
- 회전을 할 때 OBB의 경우 실제 오브젝트의 영역의 모습을 유지하는 것을 확인할 수 있습니다.