언리얼 엔진 5/개발 일지

[UE5] 블루아카이브 TPS게임 개발일지 (27) - EQS를 이용한 엄폐 AI 4

ciel45 2024. 1. 2. 00:50

지난 포스팅에 이어서 BTTask_Cover, BTTask_Attack에 대해 설명할 것이다.

 

먼저 비헤이비어 트리 구조를 상기해보자면 태스크가 쓰이는 곳은 다음과 같다.

(엄폐 위치로 이동한 후, 공격 위치로 이동하여 플레이어 쪽을 본 후)

 

BTTask_Cover의 내부 구현은 다음과 같다.

먼저 상기해두자면, 이 태스크를 수행하는 것은 최적의 엄폐위치를 찾아서 그곳으로 이동한 뒤이다.

 

이동한 뒤에는 BPI_Combat 인터페이스의 Cover 이벤트를 호출한다. 그 결과로 BP_Enemy의 Cover 이벤트가 호출되어, 지난 포스팅에서 보았다시피 Crouch 노드를 실행할 것이다.

 

그 다음, Random Bool with Weight 노드를 통해 확률을 준다. Weight가 0.7임은 70%로 true라는 이야기이다.

브랜치를 하여 True일 시 IsAttacking 키를 true로 놓고, 태스크를 끝낸다.

False일 시 태스크를 그대로 종료한다. 즉 엄폐상태가 유지된다.

 

 

 

BTTask_Attack의 구조는 다음과 같다.

 

인터페이스의 Attack을 호출하면 BP_Enemy의 Attack이 호출된다. 그 내용을 상기해보자면 다음과 같다.

 

다시 태스크를 살펴보자면, 사격 후 Random Float in Range를 활용하여 1~2초 뒤에 Recover 이벤트가 실행되도록 한다.

Recover 이벤트는 IsAttacking 키를 다시 false로 만들고, 태스크를 끝낸다.

 

 

그리고, 만약 적이 죽었다면 이 방대한 과정을 모두 할 필요가 없다.

따라서 모든 시작점인 AI_Enemy(AI Controller)를 BP_Enemy에서 뜯어낼 것이다.

 

이를 위해 오랜만에 C++ 코드를 추가했다.

void AEnemy::Die(FDamageEvent const& DamageEvent)
{
	//죽을 때 래그돌 효과 (함수가 너무 길어져서 따로 떼어냄)
	RagdollEffect(DamageEvent);

	//AI 컨트롤러 떼기
	GetController()->UnPossess();
}

 

 

잊지 말아야 할 것이 하나 남았다. BP_Enemy의 AIController인 AI_Enemy가 사용하던 비헤이비어 트리는 BT_Enemy이지 BT_FindCover가 아니다.

 

따라서 BT_FindCover는 BT_Enemy 안에 넣어주어야 한다.

 

 

비헤이비어 트리도 근본은 '트리'이므로 가능하다. BT_Enemy 안에 Run Behavior 노드를 추가해주면 된다.

디테일 패널에서 BT_FindCover 선택

 

 

 

 

이렇게해서 엄폐, 공격 시스템을 다 만들었다.

 

혹시 이 포스팅을 참고하여 엄폐 시스템을 만드시는 분이 있다면, 중간중간에 AI가 이상한, 예상치 못한 행동을 하는 경우가 수도 없이 많을 것이다. 또한 제작 과정이 워낙 방대하여 세세한 수정은 미처 포스팅으로 담지 못한 부분도 있다.

 

만약 그런 경우가 발생한다면,

데코레이터 조건을 꼼꼼히 살펴보거나,

비헤이비어 트리에서 중단점을 설정해놓고 디버깅해보거나,

화면 한쪽에 비헤이비어 트리 창을 띄워놓고 어떻게 진행되는지 눈으로 확인해보거나 등,

여러 방법을 총동원하여 해결하는 것을 추천드린다.

 

사실 이 글도 전체적으로는 외국 유튜브를 보면서 따라간 것인데, 따라가봤더니 영상과는 다른 엉뚱한 결과가 나와 디버깅하느라 진을 뺀 적이 많다.

 

 

다음은 테스트 영상이다.

https://www.youtube.com/watch?v=oBSYpHCbP3A&ab_channel=Ciel45