언리얼엔진

51. 원거리 공격 Enemy AI 만들기

찬이2 2023. 7. 23. 17:34

원거리 공격 Enemy 생성

원거리 공격을 하는 Enemy를 만들기 위해 BP_Enemy를 상속하여 BP_Enemy_Ranged 자손 블루프린트를 만들었다.

BP_Enemy_Ranged에게 적용할 비헤이비어 트리 BT_Enemy_Ranged도 새로 추가한다.


BB_EnemyRanged 블랙보드

BT_Enemy_Ranged 비헤이비어 트리에 적용한 블랙보드

먼저 비헤이비어 트리에 사용할 블랙보드 BB_Enemy_Ranged를 만들어서 Blackboard Asset에 적용하였다.

BB_Enemy_Ranged 블랙보드 디테일에서 전에 만들었던 BB_Enemy_Melee 블랙보드를 부모로 설정하였다.

BB_Enemy_Ranged의 부모로 BB_Enemy_Melee를 적용

 

이렇게 블랙보드를 설정하면 BB_Enemy_Melee에 추가했던 Target과 SelfActor 키를 쓸 수 있게 되는 것이다.


BT_Enemy_Ranged 비헤이비어 트리

먼저 루트 바로 밑에 Selector를 연결해준다. 이 Selector에 BTS_FindTarget 서비스를 추가하여 Enemy가 Target을 탐지할 수 있도록 한다. (Target 지정해주기)

 

이어서 Sequence를 추가하고, Blackboard 데코레이트를 추가해준다.

여기서는 Target에 값이 있는지(Target : Is Set)를 검사해줄 것이다.


이제 Sequence 밑에 각각 Target발견 시 회전 / 스킬 활성화 / 스킬 공격 태스크를 순서대로 연결해줄 것이다.

 

 

Rotate To Face BBEntry 태스크

Sequence 밑에는 이어서 Rotate To Face BBEntry를 통해 Enemy가 Target 감지 시, 바로 돌아보도록 했다.

Rotate To Face BBEntry 디테일에서

- Precision(각도 단위 정밀도 성공 조건) : 1.0

- Blackboard Key : Target

 


BTT_ActivateSkill 태스크

이어서 적을 발견하면 FireBall 스킬을 활성화 시키기 위한 새 태스크 BTT_ActivateSkill을 만든다.

 

변수로 bSwitchingAllowed(Boolean) / SkillIndex(인티저) 두 개를 추가하여 인스턴스 편집가능을 활성화해준다.

 

Receive Tick AI 이벤트를 추가하고 제일 먼저 IsState로 Idle인지 검사한다.

IsState(Idle)이 True라면 IsSkillActivated로 스킬 활성화 여부를 한번 더 검사한다.

IsSkillActivated이 True라면 SwitchingAllowed 변수의 값을 검사하게 된다.

 

SwitchingAllowed변수가 True라면 SwtichingAllowed 변수가 True라면 SkillIndex 값에 따라서 SkillA 또는 SKillB를 실행 후 종료하게 될 것이고, False라면 그대로 종료할 것이다.

 

만약 앞의 IsSkillActivated 스킬 활성화 여부 검사에서 False일 때에는 SwitchingAllowed변수 검사를 거치지 않고 바로

Switch on Int로 스킬 활성화를 해주면 된다.

 

 

비헤이비어 트리로 돌아와서 Sequence 밑에 태스크를 연결한 후, 초기 변수의 값은 위와 같이 설정해주면 된다.


BTT_BeginActionA 태스크

저번에 생성했던 BTT_BeginActionA 태스크 그대로 사용하면 된다.


BP_Enemy_Ranged 블루프린트에서 대상을 감지할 AI Sense 추가

BP_Enemy_Ranged 블루프린트로 와서, AI Perception 컴포넌트의 Sense에 AISense_Sight를 하나 추가해서 캐릭터를 감지할 수 있도록 했다.


BP_FireBall 블루프린트에서 Target 방향으로 FireBall 날아가도록 수정

이전에 우리가 BP_FireBall에서 만든 GetDestinationData 함수는 PlayerController가 아니면 False를 반환하게 되어있다.

그래서 AI Controller가 사용하려하면 계속 Cast Failed 되어 False만 반환하게 되는 것이다.

때문에 Get Destination Data 함수가 False를 반환하게 되는 상황을 고려하여 로직을 추가해주어야 한다.

 

 

Get Destination Data 함수가 False가 되면 반환되는 Destination 값이 0, 0, 0으로 고정되어 있다.

따라서 False일 때 직접 Instigator의 Rotator를 받아와서 SpawnActor로 넘겨주도록 했다.

 

Local Variable(로컬 와일드카드)를 하나 두고, 결과값 True / False에 따라서 어떤 Rotation을 받아올 지 바뀌는 것이다.


AI가 여러 개 탐지 시, 아군 적군 구분하기(Tag 활용하기)

각각 블루프린트에 있는 Tag를 활용하여 인식된 객체를 구분할 것이다.

먼저 BP_Player에 Tag에는 A를 추가하고, BP_Enemy의 Tag에는 B를 추가한다.


그 다음, BTS_FindTarget 서비스에서 Get Currently Perceived Actors로 감지된 Out Actors들을 For Each Loop with Break로 모든 원소를 하나씩 확인할 것이다.

 

각각의 원소(Array Element)에서 Actor Has Tag를 통해 특정 Tag의 이름과 같다면 해당 원소를 Target에 넣고 바로 Break로 Loop를 깨주는 방법으로 감지된 대상 중 Player만 공격하도록 했다.