1. DotProduct가 궁금했던 이유
게임 개발에서는 두 벡터 간의 관계를 계산하는 작업이 자주 발생합니다.
특히, 적이 플레이어를 탐지하는 로직을 구현할 때, 적의 시야각(Field of View)과 적-플레이어 위치 관계를 계산해야 하죠.
이를 구현하면서 DotProduct(내적)를 사용하는 코드와 관련 설명을 접하게 되었고, 이를 더 깊이 이해하고자 했습니다.
2. DotProduct란 무엇인가?
DotProduct는 두 벡터의 방향 관계를 계산하는 방법입니다.
수학적으로 다음과 같이 정의됩니다:
DotProduct(A, B) = |A| * |B| * cos(θ)
- |A|, |B|: 벡터 A와 B의 크기(길이)
- cos(θ): 두 벡터가 이루는 각 θ의 코사인 값
DotProduct 결과의 의미
- 1: 두 벡터가 같은 방향.
- 0: 두 벡터가 직각(90도).
- -1: 두 벡터가 반대 방향.
3. DotProduct를 사용하는 코드
적이 플레이어를 탐지하는 AI 로직은 다음과 같은 흐름으로 작성됩니다:
// 플레이어 위치에서 적 위치로의 방향 계산
FVector Distance = PB->GetActorLocation() - CB->GetActorLocation();
// 적과 플레이어 사이의 거리가 시야 범위를 초과하면 탐지 실패
if (Distance.Length() > SightRange)
{
return EBTNodeResult::Failed;
}
// 적의 전방 방향과 거리 벡터를 정규화
Distance.Normalize();
FVector AIForward = CB->GetActorForwardVector();
AIForward.Normalize();
// DotProduct를 사용해 두 벡터 사이의 각도를 계산
float DotResult = AIForward.Dot(Distance);
float AngleBetweenVector = FMath::Acos(DotResult);
// 시야각을 초과하면 탐지 실패
if (SightAngle < AngleBetweenVector)
{
return EBTNodeResult::Failed;
}
코드 흐름 설명
1. 거리 계산
플레이어와 적 간의 방향벡터(Distance)를 구합니다.
Distance = PlayerPosition - EnemyPosition
2. 시야 범위 확인
벡터의 길이(거리)가 시야 범위를 초과하면 탐지 실패
if (Distance.Length() > SightRange)
3. 벡터 정규화
벡터의 방향만 남기기 위해 길이를 1로 만듭니다.
NormalizedVector = Vector / Vector.Length()
4. DotProduct 계산
적의 전방 방향 벡터(AIForward)와 플레이어의 방향벡터(Distance)의 DotProduct를 계산
DotResult = AIForward.Dot(Distance)
5. 시야각 체크
두 벡터의 각도가 시야각을 초과하면 탐지 실패
if (AngleBetweenVector > SightAngle)
4. DotProduct와 각도 계산 시각화
1) DotProduct의 결과
DotProduct는 두 벡터 간의 방향 관계를 숫자로 나타냅니다:
- cos(0°) = 1: 두 벡터가 완전히 같은 방향.
- cos(90°) = 0: 두 벡터가 직각(90도).
- cos(180°) = -1: 두 벡터가 완전히 반대 방향.
2) 시야각(90도) 계산 예시
조건:
- 적은 (0, 0) 위치에 있고, 플레이어는 (1, 1) 위치에 있습니다.
- 적의 시야각은 90도로 설정됩니다.
시각적 표현:
- 빨간 점: 적의 위치.
- 파란 점: 플레이어의 위치.
- 빨간 화살표: 적이 바라보는 정면 방향.
- 녹색 점선: 적의 시야각(90도 범위).
적의 시야각 내에 플레이어가 포함되어 있어, 적이 플레이어를 탐지할 수 있는 상황을 나타냅니다:
5. 결론
DotProduct는 게임 개발에서 적 탐지, 캐릭터 시야, 빛 반사 계산 등 여러 상황에서 사용됩니다.
이 예시를 통해 두 벡터 간의 방향 관계를 효율적으로 계산할 수 있음을 확인할 수 있습니다.