· 오늘 공부한 내용
오늘은 어제 정리한 내용들을 바탕으로 설계를 수정하기 위해서 코드를 리뷰해보았다.
우선적으로 수정해야 할 것으로 보이는 부분이 크게 2가지가 있었는데, Task를 등록하는 과정과 블랙보드 참조 및 사용에 대한 부분이다.
1. Task 등록 부분
현재 구현된 내용상 모든 노드들은 공통적으로 base node를 상속받고, 크게 평가 함수 부분의 내용만 달라지도록 구현이 되어있다. 그런데 코드 리뷰를 하다보니 여기서 문제점이라고 할까, 눈에 밟히는 부분이 있었다.
리프 노드(Task)들의 수가 많아지면 상속을 받는 클래스들이 불필요하게 너무 많아진다는 점이다.
생각을 정리해 본 결과 이 기능을 구현하자면 크게 2가지 방법으로 처리할 수 있을 것 같다.
- 클래스 상속으로 task 정의(복잡한 구현, 참조가 필요한 경우에 유용하다) -> 현재 구현 방식
- 이벤트 등록 방식으로 task 추가(등록시에 필요한 참조 변수 같이 넘겨줘서 작동하는 방식으로) -> 대안으로 생각한 방식
사용자의 입장에서는 이 부분을 이벤트로도 처리하면 더욱 간단할 것 같다.
게다가 복잡한 Task가 아닌 이상 평가 부분에서 사용하는 변수 외에는 크게 달라지는 내용이 없으므로...
그래서 다시 생각해본 결과, 상속 방식과 이벤트 함수만 재정의하는 방식 둘 다 지원하도록 설계를 변경해야 할 것 같다.
대략적으로 구상된 수정 방법은 다음과 같다.
- 외부에서도 태스크 이벤트를 사용할 수 있도록 하는 기능을 평가 함수 안에 구현하고 이벤트가 정의 되어 있으면 호출하도록 한다.
- 이벤트 등록 기능은 Base node에서 구현하고, 태스크에서 호출가능하게끔 세팅한다. 즉, 자식 노드에서는 평가 함수에 기본적인 자신의 기능을 가지고 있고, 추가로 이벤트 함수가 정의되어있는지 확인하고 정의가 되어 있다면 해당 이벤트를 호출하는 기능을 추가하면 된다.
- 이 방식에서 고민이 되는 점이 있는데, 자식 노드에서 우선 부모 node(이벤트 호출만 해줌) 쪽 함수를 먼저 호출하고 자신의 함수를 이어서 호출하게 할지 / 반대로 자기 자신 것을 호출하고, 부모 함수를 이어서 호출하도록 할지다. 이렇게 되면 먼저 자신의 노드를 평가하고 이벤트를 호출하게 된다. 순서로 따지자면 다르지만 지금 당장 생각하기에 결과적으로 큰 차이가 있을 것 같지는 않다. 해서 일단은 후자쪽으로 수정 작업을 진행할 계획이다.
2. 블랙보드 참조 및 이용
현재 블랙보드는 글로벌과 로컬 클래스가 서로 나누어져 있다.
그런데 언리얼 비헤이비어트리를 다시 살펴보니 아무래도 로컬 변수를 사용하는 게 일반적인 것으로 보인다.
따라서 클래스를 따로 분리하지 않고 로컬 변수를 기본으로 사용하되, AI관련 Main 스크립트에서 static으로 블랙보드 변수를 선언해 글로벌 변수로 사용하면 될 것 같다.
이를 위한 밑작업을 해야 하는데
class BehaviourTree
{
private Node root;
public BehaviourTree(Node root)
{
this.root = root;
}
public IEnumerator RunBT()
{
while (true)
{
root.Evaluate();
yield return new WaitForSeconds(0.5f);
}
}
}
수정하게 되면 현재 작성된 생성자 부분에서 root.SetTree(this); 을 추가로 작성해 처리 해주고 이 SetTree() 함수를 이용해서 모든 노드가 동일한 블랙보드를 참조할 수 있는 일종의 링크를 만들고자 한다.
이렇게 하면 나머지 노드들은 getTree() 함수를 통해서 최상위 Root가 어디 있는지 바로 알 수 있고, 이를 이용해서 Root에 할당 되어 있는 블랙보드를 알 수 있을 것이다.
또 해당 부분 외에 Node에서 데이터를 Get/Set 하는 부분이 최근에 작성한 블랙보드와 호환되지 않아 추가 수정하기로 했다.
· 어려웠던 내용
밑바닥에서부터 헤딩해가며 만들다보니 리뷰를 할 때마다 다양한 문제가 계속 쏟아진다. 이걸 모두 해결하고자하면 정말 많은 시간이 필요할테니 적당히 타협해서 작업해야하는 데.. 설계엔 답이 없다! 라고 생각하지만 약간 막막한 것은 사실이다. 그 점 외에 다른 고민은 없었다.
· 궁금한 내용과 부족한 내용
현재 생각해둔 설계에서는 데코레이터 부분을 사용하지 않아도 시퀀스로 로직을 처리할 수 있는데, 설계를 바꾸면서 다시 확인해보니 아무래도 병렬처리 부분이나 조건에 대한 부분이 앞으로 필요하지 않을까 하는 생각이 든다. 이 점을 어떻게 처리하면 좋을까? 언리얼 비헤이비어 트리를 레퍼런스 삼고는 있지만 다른 좋은 방법이 없을지 궁금하다. 관련 자료를 더 찾아볼까..
· 느낀점 또는 목표
오늘은 전반적인 리뷰를 했으니 남은 한 주동안 내용을 수정하고, 어느정도 작동 되는 것을 확인한 뒤에 다시 설계를 살펴보아야겠다. 해당 기능에 대한 구현 목표는 최대 다다음주까지 완성된 기능 데모를 만드는 것이고, 이 부분까지 완성되면 비쥬얼 스크립팅을 대신할 Json 활용 트리 정의에 대해 추가적으로 고민하고 적용해볼 것이다.
'TIL' 카테고리의 다른 글
23-05-11 (0) | 2023.05.11 |
---|---|
23-05-10 (0) | 2023.05.10 |
23-04-05 TIL (0) | 2023.04.05 |
220802 디버깅 (0) | 2022.08.02 |
220714 비헤이비어 트리 (Behavior Tree, BT) 정리 (0) | 2022.07.14 |