본문으로 건너뛰기
게임 수학 · 게임 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
  1. 문제 1“거리와 범위 판정”에서 혼동하기 쉬운 개념을 올바르게 연결한 것은 무엇인가요?
  2. 문제 2“거리와 범위 판정”의 작업 기준으로 ‘공격보다 Chase를 먼저 검사’을 진단하거나 바로잡은 선택은 무엇인가요?
LESSON STATUS

학습을 마쳤나요?

직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.

5강. 거리와 범위 판정 미완료 상태