Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

게임 개발 메모장

[ UE5 ] BehaviorTree : Blackboard 본문

언리얼 엔진/AI

[ UE5 ] BehaviorTree : Blackboard

Dev_Moses 2023. 12. 21. 10:27

 

사용자 혹은 AI(인공 지능)으로 제어 할 수 있는 Object 

 

 

 

AI Controller 에 기획 의도에 맞게 동작할 수 있게 작성한 BehaviorTree를 RunBehaviorTree를 활용해서 실행시킨다.

 


Blackboard

 

1) Blackboard는 AI Bot이 의사결정을 하기 위해 필요한 정보를 저장하는 저장소이다. 

2) 이 정보는 현재 AI Bot이 처한 여러 상황을 표현하게 되는데 하나의 AI Bot이 아닌 

    다수의 AI Bot이 협력과 의사결정을 위해 공유하는 공유 메모리로서의 역할 또한 할 수 있다.

 

왜 Blackboard를 사용할까?

1 효과적인 이벤트 주도형의 행동을 만들기 위해

(To Make Efficient Event-Driven Behaviors)

일반적으로 게임에서 인공 지능 로직은 매 프레임마다 업데이트하지 않는다.

인공지능 로직으로 인해 Frame Rate에 부하를 주지 않아야 하기 때문이기도 하고,

실제 인공지능 로직의 변화가 그렇게 자주 발생하지 않기 때문이다.

 

BT를 언제 업데이트 하느냐의 문제를 언리얼 엔진에서는 BT에 담긴 데이터가 변화할 때

업데이트 하겠다라고 방침을 정한 것 같다.

 

따라서 BT에서 사용하는 데이터가 변화할 때 마다, 데이터가 BT에게 '내가 변화했어요~' 라고 알려줘야

한다. Blackboard는 이런 점에서 특화된 자료라고 보면 된다.

 

즉 Blackboard가 변화할 때 마다 이벤트를 BT에 전달하여,

이를 기점으로 BT의 업데이트가 이루어진다는 것이다.

 

이를 함축적으로 표현한 말이 바로 '효과적인 이벤트 주도형 행동'을 Blackboard를 통해 만들겠다라는 말.


2 빠른 캐쉬 연산을 위하여 (To Cache Calculations)

동일한 데이터가 반복적으로 같은 연산을 수행한다면, 분명 성능 상 좋지 않은 영향을 끼친다.

이미 계산된 연산 결과를 캐쉬한다면 BT는 반복적인 재연산을 할 필요가 없을테니 성능적인 이점

지니게 될 것이다. Blackboard의 데이터는 이렇게 이미 계산된 결과를 반복 계산하지 않도록 캐쉬 메커니즘이 도입되어 있다.

 

[ 예시 상황 ] 

AI가 SightSensing을 하면서 적군을 발견하면 담당 Task에서 적군의 위치 변수에

적군의 위치 값을 기입을 시킨다.

 

비헤이비어 트리 동작을 할 때 적군에 위치를 한번씩 검사를 하는 Task를 사용을 할 때

해당 Task의 적군의 위치 변수를 비헤이비어 트리에서 사용하고 있는 BlackBoard의 

적군의 위치 벡터 변수를 비헤이비어 트리에서 사용하고 있는 담당 Task를 클릭한 후

디테일 패널에서 알맞게 매핑을 시켜준다.

 

적군의 위치가 갱신이 되면 그 다음 Task에서 적군의 위치를 감지를 했을 때

프로그래밍한 내용을 실행을 시킨다.  

 

해당 Task에서의 변수를 BlackBoard에서의 필요한 변수로 매핑을 시켜준다.

 

Task에서 필요한 변수를 인스턴스 편집으로 만든다.

 

Task1 에서는 블랙보드 값을 쓰고  

 


Task2 에서는 Write 된 블랙보드 값을 Print 해준다.


3 데이터의 집중화를 위하여 (To Centralize Data)

Blackboard는 데이터를 한 곳에 모아두기에 좋은 장점을 지니고 있다.

만약 Blackboard가 없다면, 각각의 클래스에 산재한 데이터를 참조하기 위해

지저분한 여러 절차를 거쳐야 할 게 분명하다.

 

( 예를 들어, Blueprint에서 현존하는 다른 Class Blueprint의 데이터를 가지고 올려할 때

얼마나 많은 노드를 반복적으로 만들어야 하는지... )

이런 점은 데이터를 캡슐화하는 장점도 또한 지니고 있다.

 

 


 

BT의 Task들은 프로그래밍 언어로 치자면 서브루틴 또는 함수로 간주 된다.

프로그래밍 언어에서 함수에 파라미터를 집어넣어 처리하듯 BT도 이런식으로 접근한다면

분명 효율적일 것.

 

함수의 효율성은 단지 파라미터를 사용할 수 있다는 것 뿐 아니라,

한번 만들어 놓으면 재사용이 가능하다는 큰 장점을 지닌다.

 

BT를 만들때도 마찬가지로 이러한 재사용성의 고려가 분명히 필요하다.

잘못된 Data의 사용은 직관적이고 단순하게 표현할 수 있는

BT의 큰 장점을 한 순간에 무너트릴 수 있다.

하지만, Task 내에 Data를 선언하게 되면 필연적으로 이런 문제가 생긴다.

 

이를 해결할 수 있는 좋은 방법은 Task들과 Data를 분리하는 것

BT가 필요한 Data를 외부에서 따로 선언하고 관리함으로서 이러한 독립성을 유지할 수 있다.

이렇게 하면 BT의 각 Task들은 Data가 필요할 때 이를 질의(Query)해서 들고 오거나,

쓰면(Write) 깔끔히 해결이 된다.

 

( 이건 Design Pattern에서 객체와 객체 간의 상호작용은 구성(Composite)을 사용하는게 좋다라는 것과

비슷한데 즉, 필요한 Data는 별도로 캡슐화해서 독립성을 보장하는 것 )

 

이러한 사유로 BT에서는 Data를 별도로 관리하게 되는데 이곳을 BlackBoard라고 한다.