45. AI 만들기(비헤이비어 트리 / 블랙보드 / 서비스)
AI 만들기
비헤이비어 트리
콘텐츠 브라우저에서 우클릭 - 인공 지능 - 비헤이비어 트리를 추가했다.(BP_Example)
위젯 블루프린트처럼 2가지의 탭 비헤이비어 트리 / 블랙보드로 나뉘어져 있는 것을 볼 수 있다.
먼저 비헤이비어 트리부터 알아보자.
제일 먼저 Root 노드 하나만 있을 것이다. 이름 그대로 트리 구조의 형태를 띄고 있으며, 자식 수에 제한은 없다.
비헤이비어 트리에서 우클릭하면 만들 수 있는 Composites / Tasks 가 있는 것을 볼 수 있다.
Composites(조합/합성)
Tasks를 자식 노드로 묶어놓을 수 있는 내용이다. 루트 다음으로 이어지는 것은 무조건 Composites 이다.
Selector
- 자식 노드가 왼쪽에서 오른쪽 순으로 실행된다.
- 모든 자식 노드 중 하나라도 성공한다면 Selector도 성공이다(OR : 성공 즉시 돌아옴)
- 실행 중인 자식노드가 실패하면 다음 노드로 넘어간다.
- 만약 현재 자식노드가 성공하면 나머지 노드들은 실행하지 않는다.
Sequence
- 현재 실행중인 자식노드 성공 시, 다음 노드를 실행한다.
- 현재 실행중인 자식노드 실패 시, 다음 노드들은 실행하지 않고 끝난다
- 모든 자식노드가 성공해야 Sequence도 성공이다(AND : 실패 즉시 돌아옴)
Simple Parallel(평행/병렬)
- 자식노드 두 개를 붙일 수 있다(보라색 : Main task / 검은색 : Sub task)
- FinishMode : Main task 종료 이후의 행동 (Immediate : 즉시 종료 / Delayed : Sub task 기다림)
Tasks(작업/업무)
Wait
- 지정한 시간만큼 대기 (Wait Time : 대기 시간 / Random Deviation : 랜덤 편차)
Play Animation
- Animation to Play : 재생하고자 하는 애니메이션 지정
- 해당 애니메이션의 재생이 끝나고 다음으로 노드로 넘어간다
Move To
- 목적지를 정해주어야 한다.
- Acceptable Radius : 도착 좌표의 반경 지정값 이내로 들어오면 성공
비헤이비어 트리 적용시키기
일단 위와 같은 비헤이비어 트리를 만들었다. Sequence를 통해 Wait - Play Animation 순으로 실행이 계속 반복된다.
Wait에서 2.5초 +- 0.5초 머물다가 Play Animation에서 Attack_1 애니메이션 시퀀스를 재생하게 된다.
이제 BP_Enemy로 와서 방금 만든 BT_Example(비헤이비어 트리)를 적용시켜줄 것이다.
BeginPlay이벤트에서 AIController를 받아와 Run Behavior Tree로 특정 비헤이비어 트리를 재생시킨다.
따라서 Behavior Tree 변수를 만든 뒤, 기본값으로 BT_Example을 넣고 Run Behavior Tree에 연결시켜주면 된다.
비헤이비어 트리 특징
노드의 우측 상단에 보면 숫자들이 각기 다른 것을 볼 수 있다. 이는 노드의 실행 순서를 나타내는 것이다.
비헤이비어 트리는 전위순회 방식으로 실행이 되는 것을 알 수 있다.
여기서는 노드의 위치에 따라서 실행 순서가 달라지니 주의해주어야 한다.
* -1은 연결된 것이 없어서 실행되지 않는다는 뜻이다.
블랙보드 데이터 에셋(Black board)
비헤이비어 트리에서 Move To task에 목적지를 주기 위해서 블랙보드를 사용하게 된다.
비헤이비어 트리 위쪽 목록에 새 블랙보드를 눌러 블랙보드(BB_Example)을 만들게되면 블랙보드 탭이 활성화된다.
기본적으로 SelfActor 변수가 만들어져 있는 것을 볼 수 있다. 이는 비헤이비어 트리를 실행하게되는 Pawn을 말한다.
좌측의 블랙보드 탭에서 새 키를 눌러 목적지를 담을 변수 Destination(Vector)를 만든다.
(비헤이비어 트리의 멤버 변수같은 느낌이다)
새로 만든 Destination의 디테일을 보면 Entry Name(이름), Entry Description(주석), Key Type(유형)이 있다.
- Instance Synced : 이 블랙보드를 사용하는 모든 대상이 해당 키를 사용할 수 있음
- Parent : 이미 만들어져 있는 블랙보드를 현재 블랙보드가 상속받음
서비스 노드 블루프린트
블랙보드의 Destination 키에 값을 넣어주기 위해서 새 서비스를 생성한다(BTS_SetDestination)
이렇게 새로 블루프린트가 만들어졌는데, 클래스 디폴트에서 보면 대표적으로 Interval(이 서비스를 수행할 간격),
Random Diviation(랜덤 편차)가 있다.
오버라이드 가능한 함수를 보면 크게 Activation / Deactivation / Search Start / Tick 4가지로 나뉘어져 있다.
여기서 우린 BP_Enemy에 활용할 것이기 때문에 AI를 사용하면 된다.
변수 Destination을 추가했다. 유형은 Blackboardkey Selector로 하며 인스턴스 편집가능을 켜두었다.
여기까지 해두고 다시 비헤이비어 트리로 와서 Move To에 BTS_GetDestination 서비스 노드를 추가한다.
Move To 노드 우클릭 - 서비스 추가 - BTS_SetDestination 서비스 노드 선택을 하여 추가해준다.
추가한 서비스 노드 선택 후, 디테일에서 Destination의 값을 Destination으로 선택해주었다.
이후 비헤이비어 트리를 보면 Move To 아래의 서비스 노드가 먼저 실행되고 Move To가 실행되는 순서가 된 것이 보인다.
다시 BTS_GetDestination 서비스 노드 블루프린트로 돌아와서 Destination에 값을 넣어줄 로직을 만들어야한다.
아까 만들었던 Destination 변수에서 Set Blackboard Value as Vector 노드를 연결시켜준다.
* 뒤에 as Vector말고 여러가지 유형이 있는데, 이는 자신이 어떤 형식인지 알 수 없기 때문에 종류별로 다 있는 것이다.
Value로 들어오는 Location을 핀 분할한 뒤, X축과 Y축에 각각 Random Float in Range를 통해 랜덤한 값을 넣어주었다.
Z축은 100으로 고정시켰다.
다시 비헤이비어 트리로 돌아와서, Move To 노드의 디테일에 Blackboard Key를 Destination으로 지정해주면 된다.
내비 메시 바운드 볼륨
AI가 움직일 수 있는 범위를 지정해주어야 비헤이비어 트리의 Move To로 AI가 움직일 수 있다.
액터 배치 - 볼륨 - 내비 메시 바운드 볼륨 선택하여 레벨에 추가해주었다.
그렇게 추가된 내비 메시 바운드 볼륨의 트랜스폼은 원점으로 옮기고 스케일을 각각 10씩 키워주면 현재 레벨에 있는
맵의 크기와 비슷하게 나온다.
뷰포트에서 단축키 P를 누르면 현재 네비게이션의 범위가 어떻게 지정되어 있는지 초록색으로 나타내준다.
이렇게 AI들이 움직일 수 있는 공간을 지정해준 것이다.