언리얼 - 게임 개발

첫 게임 개발(15) _ EQS 기초

earth-star 2024. 6. 24. 16:47

적 AI의 움직임을 보다 다양하게 구현하기 위해서 EQS라는 시스템이 있는데 이를 간단히 다뤄 볼 것이다.

생소한 영역이라 좀 어렵게 느껴졌고 적 보스의 움직임 제어에 필수이기 때문에 열심히 파고 들어야 할 영역인 것 같다.

 

블루프린트의 AI에서 Env Query라는 블프가 있다.

이를 생성하면 원, 도넛모양, 사각형 등등 다양한 모양의 EQS를 만들 수 있는데 

일직선으로 EQS를 만들어야 하는 2D에 맞는 월뿔모양의 EQS를 만들었다.

 

 

 

이후 아래에 Distance에 따른 가산점을 주는 조건을 붙여 가까운 거리를 더 우선적으로 이동하도록 하였다.

 

 

그 다음으로 EnvQueryContext_BlueprintBase 블프를 만든다.

 

임시로 사용하는 EQS_TestingPawn를 만든 뒤 Context 블프에서 위와 같이 오버라이드 함수를 생성하여

플레이어 스타트에 연결한다.

 

위와 같이 플레이어 스타트 기준으로 앞으로 EQS가 생성된 것을 볼 수 있다.

길이를 600에 간격을 200으로 만들었기 때문에 3개가 있는 것을 볼 수 있다.

적은 이 3개의 EQS사이를 이동할 것이다.

 

그 다음으로 블랙보드에 AttackRadius와 DefendRadius 플로트형 변수를 만든다.

AttackRadius는 적이 공격하기 위해 서 플레이어에게 다가오는 거리이고

DefendRadius는 적이 일정 범위 밖으로 도망간 경우 빠르게 따라가기 위한 거리이다.

즉 DefendRadius만큼의 거리안에서 플레이어 주위를 맴도는 반경이다.

 

두 변수를 BT에 전달하기 위해서 BPI_EnemyAI에 GetIdealRange 함수를 생성하고

BP_Enemy_Human에서 함수를 가져와 위와 같이 두 변수의 값을 입력한다.

 

입력한 두 변수를 BT에 전달하기 위해 AIC_Enemy_Base에서 GetIdealRange 함수를 가져와 두 변수를 Set Float 함수로

각각 블랙보드에 넣는다.

 

다음으로 DefendRange를 벗어났는지의 유무를 체크하기 위한 데코레이터를 만들고 위와 같이

플레이어와 적의 거리가 IdealRange(설정할 값은 DefendRange) 안에 있는지 여부를 Bool 형태로 반환한다.

 

BT에서 Run EQS Query로 아까 만든 EQS를 할당해준다.

이동속도는 Walking으로 플레이어의 앞의 3개의 기준점들을 천천히 앞뒤로 이동할 것이다.

이는 인게임에서 적이 마치 플레이어 주변을 맴돌며 간을 보는 형태의 느낌을 만들 수 있다.

 

그 다음으로 원래의 Moveto 노드를 MovetoIdealRange로 바꾸고 Ideal Range를 AttackRadius로 바꾸어준다.

위에서 설정한 값대로 150 거리에서 플레이어를 공격할 것이다.

또한 위에 언리얼에서 기본적으로 제공하는 Cooldown 조건을 붙이고 10초로 설저하여

10초마다 한번씩 공격을 한 뒤 플레이어 주변을 맴돌도록 한다.

 

그 다음으로 플레이어가 일정 범위 밖으로 벗어났을 시 Sprinting 속도로 빠르게 범위까지 쫓아가는 시스템을 만든다.

 

아까 만든 데코레이터를 위에 붙이고 역 조건을 체크하여 플레이어가 Ideal Range(DefendRadius) 안에 있지 않을 때

아래의 노드들을 실행하여 플레이어를 빠르게 쫓도록 한다.

 

최종적으로는 위와 같은 형태가 된다.

적이 Attacking 상태가 되면 우선적으로 왼쪽에 있는 Attack으로 가서 플레이어를 공격하게 된다.

Cooldown 10초가 있기 때문에 10초간은 다시 공격을 하지 못한다.

따라서 오른쪽에 있는 IsWithInIdealRange 조건을 확인하고 만족하면 거짓이기 때문에(역 조건)

오른쪽으로 가서 설정한 EQS로 플레이어 주변을 천천히 맴돈다.

그러다가 10초가 지나서 Cooldown이 꺼지면 다시 우선순위인 왼쪽으로 가서 플레이어를 공격하게 된다.

 

만약에 EQS로 맴도는 상태에서 플레이어가 도망가면 IsWithInIdealRange 조건을 만족하지 못하게 되어

플레이어를 빠르게 쫓아가게 되고 다시 범위 안에 들어오면 조건을 만족하여 다시 EQS상태로 돌아간다.

 

 

잘 동작하는 것을 볼 수 있다.