48. AI의 Sound 감지 / AI 인식된 대상 받아 넣기
AI Perception 컴포넌트의 Sound 감지
실제로 AI가 자동으로 소리를 감지하지 못한다. 때문에 소리가 발생하는 대상이 직접 MakeNoise / Pawn Make Noise 함수를 호출해야 AI가 소리가 났다는 것을 인식한다.
이번에는 검을 휘두를 때 타이밍에 맞게 소리가 발생하고 이를 AI가 인식할 수 있도록 해볼 것이다.
공격 시 사용하고 있는 Attack_1 Montage에서 사용할 노티파이를 만들었다.(AN_MakeNoise)
AN_MakeNoise
Received Notify 오버라이드 함수를 추가하고 Play Sound at Location을 통해 사운드의 위치와 방향을 지정하고 재생한다.
해당 몽타주 Mesh Comp의 Owner를 받아와서 Location / Rotation을 넘겨주면 된다.
Play Sound at Location으로 사운드가 재생됬다면 Make Noise를 통해서 사운드가 발생했다고 호출을 보내는 것이다.
* Notify 내에서는 Make Noise 함수가 검색되지 않는다. 따라서 외부에서 복사해오거나, 우클릭 창에서 컨텍스트에 따라를 해제하여 모든 함수를 볼 수 있도록 바꿔주면 된다.
이렇게 AN_MakeNoise 노티파이를 만든 뒤, Attack_1 Montage에서 노티파이 트랙에 추가해주면 BP_Enemy의 AI가 잘
감지하는 것을 볼 수 있다.
AI Perception으로 인지된 Target 받아 사용하기
이벤트 그래프에서 AI Perception 컴포넌트에서 인지한 대상을 받아오려면 3가지의 함수가 있다.
- Get Currently Perceived Actors : 현재 인지 범위 안에 있는 Actor 구하기
- Get Known Perceived Actors : 인식된 적이 있고, 인지 범위 바깥에 나갔어도 아직 인식 수명이 남아있는 모든 Actor
- Get Perceived Actors : 이제는 사용하지 말라고 한다
Sense to Use에서 특정 Sense의 인지 결과만 받아올 수도 있지만, None으로 두면 모든 Sense의 결과를 받아온다.
BTS_FindTarget 서비스 생성
여기서 우리는 Get Known Perceived Actors 함수를 이용하여 인지된 Actor들을 받아올 것이다.
BT_Enemy_Melee 비헤이비어 트리에서 Selector에 추가해줄 서비스를 새로 만든다(BTS_FindTarget )
Receive Search Start AI 이벤트를 추가하여 해당 Pawn(Enemy)의 AI Perception Component를 선택하여 받아온다.
그 AI Perception 컴포넌트에서 아까 사용하기로한 Get Known Perceived Actors함수를 통해서 인지된 Actors들이 배열에 담겨 반환된다.
여기서 반환된 Out Actors 배열의 Length의 길이가 0보다 큰지를 조건으로 Select로 이후의 실행을 결정할 것이다.
배열의 Length가 0보다 크다면 인지된 Actor가 배열에 담겨있다는 뜻이므로, True라면 배열의 0번째 원소를 Target변수에 Set Blackboard Value as Object로 넣어주게 된다.
Target 변수는 서비스에서 하나 생성하여 Blackboard Key Selector 유형으로 인스턴스 편집가능을 켜주었다.
이후 BT_Enemy_Melee 비헤이비어 트리에서 Selector에 BTS_FindTarget 서비스를 붙여주고, 서비스 디테일에서
Target 키에 Target 변수값을 지정해주면 된다.
BT_Enemy_Melee 비헤이비어 트리
비헤이비어 트리에서 Target 키값이 Set되면 Sequence로 넘어갈테고, Sequence에서는 저번에 만든 Simple Parallel을
이어준다.
* BTT_LookAt에서 테스트를 위해서 잠시 설정했던 NewVar_0 변수는 모두 지우고 다시 Actor to Face 변수로 바꿈
* Intrep Speed는 20으로 좀 더 빠르게 설정
* BP_Character의 AnyDamage에서 몽타주 On Blend out으로 빠질 때, Branch의 False에 IsState : Idle 추가하기