게임 수학 · 게임 AI 기초집LESSON 05
거리와 범위 판정
난이도입문
예상 시간35분
선수지식4강의 목표 방향
5강. 거리와 범위 판정
1. 이번 강의에서 해결할 문제
적이 공격 거리 경계에서 Chase와 Attack을 빠르게 반복하고, 적 수가 많아질수록 불필요한 제곱근 계산이 늘어납니다. 범위 비교와 상태 전환 기준을 분리합니다.
2. 학습 목표
3. 핵심 개념
두 위치 A와 B의 거리는 |B - A|입니다. 실제 거리 출력에는 제곱근이 필요하지만 “반경 안인가?”만 비교할 때는 양쪽을 제곱해 같은 결과를 얻습니다.
범위 비교
DistanceSquared <= Range × Range
DistanceSquared는 적과 플레이어의 평면 거리 제곱, Range는 추적 또는 공격 반경입니다. UE의 cm 단위를 사용하면 1200은 12m입니다.
경계에서 상태가 반복 전환되는 문제는 Hysteresis로 줄입니다. 공격 진입은 150cm, 공격 이탈은 180cm처럼 서로 다른 기준을 둡니다.
4. 단계별 실습
C++ · 파일 경로: Source/TopDownSurvival/AI/GameMathLibrary.h · 추가
GameMathLibrary.h · 추가
UFUNCTION(BlueprintPure, Category = "Game Math")
static bool IsWithinRange2D(FVector A, FVector B, float Range);
C++ · 파일 경로: Source/TopDownSurvival/AI/GameMathLibrary.cpp
GameMathLibrary.cpp · 거리 비교
bool UGameMathLibrary::IsWithinRange2D(FVector A, FVector B, float Range)
{
const float SafeRange = FMath::Max(0.0f, Range);
return FVector::DistSquared2D(A, B) <= FMath::Square(SafeRange);
}
AIController 상태 판정 예시
MathAIController.cpp · 범위 우선순위
const FVector EnemyLocation = GetPawn()->GetActorLocation();
const FVector PlayerLocation = TargetActor->GetActorLocation();
if (UGameMathLibrary::IsWithinRange2D(
EnemyLocation, PlayerLocation, AttackDistance))
{
NextState = EEnemyAIState::Attack;
}
else if (UGameMathLibrary::IsWithinRange2D(
EnemyLocation, PlayerLocation, ChaseDistance))
{
NextState = EEnemyAIState::Chase;
}
else
{
NextState = EEnemyAIState::Patrol;
}
공격 범위를 먼저 검사해야 더 넓은 Chase 조건에 가려지지 않습니다.
5. 코드와 수학·AI가 동작하는 이유
거리 제곱과 범위 제곱은 모두 음수가 아니므로 제곱근 없이 대소 관계가 유지됩니다. 상태 조건을 작은 범위부터 검사하면 Attack이 우선됩니다. 진입·이탈 기준을 분리하면 작은 위치 오차가 매 판단마다 상태를 뒤집지 않습니다.
6. 자주 하는 실수와 해결법
7. 직접 실습
8. 이해 점검 질문 3개
9. 핵심 요약
MINI QUIZ
0 / 2거리와 범위 판정 미니 퀴즈
선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.
LESSON STATUS
5강. 거리와 범위 판정 미완료 상태학습을 마쳤나요?
직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.