인공지능의 판단에 사용하는 데이터 집합을 의미한다.
AI의 의사결정은 블랙보드에 있는 데이터를 기반으로 한다.
블랙보드 데이터에 기반해 설계한 비헤이비어 트리의 정보를 저장한 애셋이다.
비헤이비어 트리의 엘리먼트 유형어로는 컴포짓, 태스크, 데코레이터, 서비스 총 네 가지가 있다.
컴포짓은 브랜치의 루트와 브랜치 실행 방식의 기본 규칙을 정의한다.
컴포짓 노드로는 셀렉터, 시퀀스, 심플 페러렐 총 3가지 종류가 존재한다.
실제 작업을 하는 노드로, AI의 행동이나 블랙보드의 값의 조정 같은 작업을 한다.
독립적으로 실행될 수 없으며 반드시 컴포짓 노드를 거쳐 실행되어야 한다.
'조건식'으로 알려져 있으며 블랙보드의 값을 기반으로 트리나 단일 노드 내 브랜치의 실행 가능 여부를 정의한다.
독립적으로 동작하지 않고 컴포짓 노드에 부착되는 노드이다.
자신의 브랜치가 실행되는 동안 정의된 빈도대로 실행된다.

비헤이비어 트리 실행 흐름은 다음과 같다.
상위 레벨에서는 위에서 아래로, 브랜치 레벨에서는 왼쪽에서 오른쪽으로 실행된다.
즉 왼쪽에 있는 브랜치일수록 실행 우선순위가 높다.

자손 노드를 왼쪽에서 오른쪽으로 수행한다.
실패하지 않는 첫 번째 자손을 찾아서 실행한다.
현재 실행 중인 자손 노드가 실패하면 그다음 노드를 실행하고,
만약 어떤 자손이 성공하게 되면 그 이후 다른 자손은 실행되지 않는다.
즉, 결과적으로 하나의 자손 노드만 성공되며 하나라도 성공하면 그 셀렉터도 성공한 것이 된다.
모든 자손이 실패하면 그 셀렉터도 실패한 것이다.
어떤 게 필요할지 결정한 다음 실행할 작업이나 브랜치를 각종 파라미터에 따라 선택할 때 유용하다.

왼쪽에서 오른쪽으로 실행하며, 자손이나 브랜치 중 하나가 작동하지 않을 때까지 순서대로 모두 실행한다.
현재 실행 중인 노드가 성공하면 그다음 노드를 실행하고, 만약 실패하면 그 이후 다른 자손의 실행을 중지한다.
자손이 실패하면 그 시퀀스도 실패한 것이며, 모든 자손이 성공해야 그 시퀀스가 성공한 것으로 처리된다.
다수의 작업을 차례대로 실행하되 그중 하나가 작동하지 않으면 브랜치 작업 전체를 취소해야 할 때 유용하다.

전체 논드 트리와 동시에 하나의 태스크를 실행할 수 있다.
디테일 패널의 Finish Mode 설정을 통해 메인 태스크가 끝나면 바로 백그라운드 트리를 중단할지, 백그라운드 트리가 끝나는 것을 기다릴지 설정한다.
타이쿤 게임에서 플레이어를 도울 알바생 AI를 만들고자 한다.
알바생 AI는
우선순위는 '도마에 있는 재료 썰기'가 '샌드위치 서빙'보다 높으며,
만약 둘 중 한 가지 일을 수행 중이라면, 나머지 일이 수행을 요하는 상태여도 현재 일을 마친 후 수행해야 한다.
즉, 하던 일을 중간에 멈추고 다른 일을 수행하러 갈 수 없다.

위와 같이 블랙보드는 비헤이비어 트리에 할당되어야 한다.

블랙보드 키는 다음과 같이 추가해주었다.
HasUncookedIngrOnCuttingBoard: 도마 위에 썰기(조리)가 완료되지 않은 재료가 있는지
HasCompletedSandwichOnTable: 완성된 샌드위치가 조리대 테이블에 있는지 (완성 여부는 샌드위치 맨 위, 아래의 재료가 빵인지로 구분한다.)
TargetDiningTable: 완성된 샌드위치를 제공할 손님이 앉아있는 테이블
IsServingSandwich: 샌드위치를 서빙 중인지
IsChopping: 도마 위에 재료를 써는 중인지
우선, 알바생은 '재료 썰기'와 '서빙' 중 하나만 수행할 것이기 때문에 루트에 셀렉터를 연결해준다.

그다음, 특정 조건에서 '재료 썰기'를 수행하도록 하려고 하는데 정해진 작업들을 연속해서 수행해야 하기 때문에 시퀀스를 연결한다.
단, 도마에서 썰기 작업을 하려면 몇 가지 조건을 충족해야 한다.
도마 위에 조리되지 않은 재료가 있어야 하고 (HasUncookedIngrOnCuttingBoard == true)
샌드위치를 서빙 중이면 안된다. (IsServingSandwich == false)
HasUncookedIngrOnCuttingBoard, IsServingSandwich 값은 AIController에서 Tick으로 설정되고 있다.
블랙보드의 키 값을 설정하는 방법은 'Set Value as (키의 변수 타입)' 노드를 사용해주면 된다.
Key Name에는 블랙보드 키의 이름을 넣어주면 된다. 일반 변수 값을 설정하는 방법과는 좀 다르다.


비헤이비어 트리에서 bool의 true는 Is Set, false는 Is Not Set으로 표현한다.
그리고 위 조건을 충족하면 정해진 작업을 수행하도록 한다.

특정 위치로 이동하는 방법은 블랙보드에 MovePos(이동할 위치 키)를 추가한 후 Set Value as Vector 노드로 MovePos 값을 지정하고 Move To 태스크로 사용하여 이동시켜도 된다.
그런데 나의 경우, 특정 액터 위치로 이동시키려다 보니 해당 액터의 콜리전으로 인해 정확히 해당 위치로 이동을 못 하는 경우가 있다.
이런 경우 위와 같이 Move To를 사용하면 이동이 불가능한 것으로 판단하여 아예 이동 시작조차 하지 않는 경우가 간혹 있어, 새로운 태스크를 만들어 그 안에서 Move To Location Or Actor 노드를 사용했다.

태스크에서는 반드시 Finish Excute를 연결해주어야 태스크가 완료된 것으로 인식한다. Success도 꼭 체크해주자.
한편 Chop 태스크에서는 한 번에 재료 썰기를 끝낼 예정이라, Chop 태스크 실행 중에 또다시 같은 태스크가 실행되어서는 안 된다.
그래서 썰기 중에는 또다시 BTTask_MoveToCuttingBoard와 Chop 태스크가 실행되지 않도록 조건을 추가해주었다.

다음으로는 완성된 샌드위치 서빙하기를 구현하였다.

대부분은 도마 썰기와 비슷한데, 한 가지 다른 점은 Sequence에 BTDecorator_NotEatingCustomerExist 데코레이터가 부착되어 있다.
다른 조건들은 블랙보드 키 데코레이터로 조건식을 추가해주었는데, '현재 식사 중이지 않은 손님이 있는지 여부'는
HasCompletedSandwichOnTable == true, IsChopping == false 조건을 만족한 후 확인할 수 있도록 따로 데코레이터를 만들었다.
데코레이터 블루프린트 안에서 함수 오버라이드를 클릭하면 다음과 같이 여러 함수들을 오버라이드 할 수 있는데

나는 조건 확인을 위해 PerformConditionCheckAI를 오버라이드한 후

다음과 같이 구현하였다.
전체 비헤이비어 트리의 모습은 다음과 같다.

각 노드 옆에 붙어있는 숫자는 실행 우선순위를 나타낸다.
참고
https://www.youtube.com/watch?v=ZupTZC_VJiA
https://lykanstudio.tistory.com/55