#18 Enemy AI 향상: EQS, LineTrace
Coding/Devlog

#18 Enemy AI 향상: EQS, LineTrace

EQS

현재는 AI가 Agro Sphere이라는 콜리젼을 가지고 있고, 여기에 메인 캐릭터가 들어오면 인식하는 구조다. 이렇게 되니 시야각 설정이 복잡해지는 문제점이 있다. 언리얼 엔진은 이에 대한 해답으로 EQS(Environment Query Sysyem)을 제시한다. EQS는 쉽게 얘기해서 Pawn과 Pawn 사이 인식을 쉽게 가능하게 해주는 인터페이스다. 인식(Perception)은 다양한 방식의 자극(Stimuli)을 통해 이뤄진다. Stimuli의 종류는 다음을 포함한다. (밑의 목록말고 더있음)

  • 소리
  • 데미지
  • 시야

그러니까 사람과 비슷하다. 누가 내 눈에 보이거나, 무언가에게 공격받거나, 들으면 우리는 그게 뭔진 몰라도 인식할 수 있다.

이러한 EQS 시스템을 쓰는 건 또 꽤 간편하다. 다음의 순서를 따르면 된다.

  1. AIControllerAIPerception Component를 추가한다. 이때, Pawn BP가 아니라 AIController에 넣는 이유는 보통 EQS에서 넘어온 정보는 BehaviorTree나 BlackBoard에 필요하기 때문이다.
    • Senses Config를 수정한다. (여기서 시각인지, 청각인지, 데미지인지 정한다)
    • Blueprint에서 OnTargetPerceptionUpdated 이벤트를 추가하고 여기에 코드를 추가한다.
  2. 관찰된 Pawn에 AIStimuli Component를 추가한다.
    • Register as Sources를 수정한다.
  3. DefaultGame.ini를 수정한다. 이는 내가 필요한 Pawn만 EQS에 등록하기 위해서다.
    • [/Script/AIModule.AISense_Sight]
      bAutoRegisterAllPawnsAsSources=false

LineTrace

LineTrace를 갑자기 추가한 이유는 AI가 일정 방향으로 걸을 때, 장애물에 걸렸는데도 계속 움직이는 것을 없애기 위해서다. 내가 생각한 방식은 단순하다. 움직일때마다 레이캐스팅(LineTrace)을 적정거리만큼 실행한다. 내가 아닌 무언가에 부딪혔다면 움직이지 않고 멈춘다. 이를 위한 코드는 다음과 같다.

bool UEnemy_AnimInstance::CheckObstacleToDirection(FVector StartPos, FVector EndPos) const
{
    FHitResult HitResult;
    FCollisionQueryParams Params;
    Params.AddIgnoredActor(TryGetPawnOwner());
    bool HasHitResult = GetWorld()->LineTraceSingleByChannel(HitResult, StartPos, EndPos, ECollisionChannel::ECC_GameTraceChannel4, Params);
    DrawDebugLine(GetWorld(), StartPos, EndPos, FColor::Red);
    return HasHitResult;
}

결과

벽이나 플레이어에 부딪힐 것 같으면 바로 멈추는 모습이다.