현재 선택된 객체가 null이 아닌지 확인.
null이 아니라면 해당 객체의 ‘BehaviorTreeRunner’ 컴포넌트를 가져온다.
애플리케이션이 실행 중 이라면, 트리뷰를 그린다.
실행중이 아니라면 에셋 데이터베이스의 인스턴스 아이디를 조회하여 트리뷰를 그린다.
Traverse 메서드로 노드를 순회하여 자식을 tree의 nodes 리스트에 추가하여 행동 트리의 모든 노드들의 클론을 생성.
에디터를 On/Off 할 때, OnEnable/Disalbe 메서드를 사용하여 OnPlayModeStateChanged 메서드 구독 및 취소로 뷰를 업데이트(새로 그려줌) (편집 모드, 플레이 모드 시에 OnSelectionChange(선택시 변경 이벤트 메서드)를 실행)
런타임 중에 에디터 변경 가능.
CreatNode메서드에서 에셋 데이터베이스에 노드를 추가하는 코드를 if(!Application.isPlaying) 으로 조건문을 걸어주어 런타임중이 아니라면 추가하지 않게 하여 런타임중에 에디터를 추가 및 삭제하며 수정 가능 (종료시 원상복귀)
런타임 중에 에디터의 수평 순서에 따라 노드 순회 순서 자동 변경(왼쪽에서 오른쪽으로)
if (!Application.isPlaying)
AssetDatabase.AddObjectToAsset(node, this);
public void Traverse(Node node, System.Action<Node> visitor)
{
if (node)
{
visitor.Invoke(node);
var children = GetChildren(node);
children.ForEach((n) => Traverse(n, visitor));
}
}
tree.nodes = new List<Node>();
Traverse(tree.rootNode, (n) => { tree.nodes.Add(n); });
private void OnEnable()
{
EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
}
private void OnDisable()
{
EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
}
// 플레이 모드 상태가 변경될 때 호출되는 메서드
private void OnPlayModeStateChanged(PlayModeStateChange obj)
{
switch (obj)
{
case PlayModeStateChange.EnteredEditMode:
OnSelectionChange();
break;
case PlayModeStateChange.ExitingEditMode:
break;
case PlayModeStateChange.EnteredPlayMode:
OnSelectionChange();
break;
case PlayModeStateChange.ExitingPlayMode:
break;
}
}
if (_treeView == null)
return;
if (!tree)
{
if (Selection.activeGameObject) // 화성화된 게임 오브젝트가 null이 아니라면
{
BehaviorTreeRunner runner = Selection.activeGameObject.GetComponent<BehaviorTreeRunner>();
if (runner)
tree = runner.tree;
}
}
if (Application.isPlaying)
{
if (tree)
_treeView.PopulateView(tree);
}
else
{
if (tree && AssetDatabase.CanOpenAssetInEditor(tree.GetInstanceID()))
{
_treeView.PopulateView(tree);
}
// 이동요소가 있다면, view의 자식들을 Sort정렬
if (graphViewChange.movedElements != null)
{
nodes.ForEach((n) =>
{
NodeView view = n as NodeView;
view.SortChildren();
});
}
// 에디터상 수평 위치 순서에 따라 노드 순서 변경 메서드
public void SortChildren()
{
Composite composite = node as Composite;
if (composite)
composite.children.Sort(SortByHorizontalPosition);
}
private int SortByHorizontalPosition(Node left, Node right)
{
return left.position.x < right.position.x ? -1 : 1;
}