BulletAnt 개발일지 (4) - RotateState

김펭귄·2026년 5월 14일

Today What I Learned (TIL)

목록 보기
119/139
post-thumbnail

Rotate State 추가 및 방향 판정 수정

기존 AI는 플레이어와 거리가 가까우면 바로 공격했다.
문제는 플레이어 방향을 보고 있지 않아도 공격이 실행된다는 점이었다.

그래서 공격 전에 반드시 회전을 수행하도록 구조를 수정했다.

기존 흐름:

Move -(일정 거리 이내)-> Attack -> Move

수정 후:

Rotate -> Move -> Attack -> Rotate

공격이 끝나면 다시 Rotate State로 돌아가 플레이어 방향을 먼저 바라본 뒤, 이동, 공격을 진행하도록 구성했다.


회전 완료 판정

회전 완료 여부는:

  • Enemy의 Forward Vector
  • Enemy의 Target을 향한 Direction

두 벡터의 내적값을 이용해 계산했다.

//RotateToTargetTask.cpp
FVector ForwardDirection = ContextActor->GetActorForwardVector();
FVector ToTargetDirection = (TargetActor->GetActorLocation() - ContextActor->GetActorLocation());
ToTargetDirection = ToTargetDirection.GetSafeNormal();
float DotResult = FVector::DotProduct(ForwardDirection, ToTargetDirection);

그리고 Data Asset에 RotationThreshold 값을 두고,
해당 각도 이내면 회전 완료로 처리했다.

//RotateToTargetTask.cpp
float Threshold = FMath::Cos(FMath::DegreesToRadians(RotateThreshold));
return DotResult > Threshold ? true : false;

이 판정은 Tick에서 계속 확인하도록 구현했다.

다만 처음에는 Tick이 호출되지 않았는데,
생성자에서 Tick 활성화를 하지 않은 것이 원인이었다.

URotateToTargetTask::URotateToTargetTask(const FObjectInitializer& ObjectInitializer) : 
	Super(ObjectInitializer)
{
	bShouldCallTick = true;
	bShouldCallTickOnlyOnEvents = true;
}

설정 이후 정상적으로 공격 후 플레이어 방향으로 회전을 하였다. 그러나 또 문제가 발생하였다


회전이 끝나지 않던 원인

이후 회전 자체는 정상적으로 수행됐지만,
플레이어 근처에서는 계속 Rotate State에 머무르는 문제가 발생했다.

원인은 방향 벡터 계산에 있었다.

나는 처음에:

  • Forward Vector
  • ToTarget Direction

이 둘이 같은 평면 위에 있다고 생각했다.

하지만 실제로는:

  • Forward Vector의 Z값은 0
  • ToTarget Direction의 Z값은 0이 아님

상태였다.

즉, 위에서 보면 같은 방향이어도
실제 3D 벡터 기준으로는 각도 차이가 발생하고 있었던 것이다.


XY 평면 기준으로 방향 판정 수정

현재 게임은 평지 기반 구조였고,
중요한 것은 높낮이가 아니라 “적이 플레이어를 바라보는가”였다.

그래서 ToTargetDirection을 XY 평면에 정사영한 뒤 사용하도록 수정했다.

ToTargetDirection.Z = 0.f;
ToTargetDirection.Normalize();

이후 해당 벡터와 Forward Vector를 내적해 방향 차이를 계산했다.

이 방식을 선택한 이유는
단순히 Threshold를 늘리는 방식은 몬스터 크기에 따라 문제가 생겼기 때문이다.

예를 들어 크기가 큰 몬스터는 Threshold를 지나치게 크게 잡아야 했고,
결국 몬스터마다 값을 따로 조정해야 하는 상황이 발생했다.

반면 XY 평면 기준으로 계산하니
몬스터 크기와 관계없이 안정적으로 방향 판정이 가능했다.

결과적으로:

  • 근거리에서도 회전 후 자연스럽게 이동 및 공격 가능
  • 연속 공격 정상 동작
  • RotationThreshold 기준 안정화

문제를 해결할 수 있었다.

profile
반갑습니다

0개의 댓글