using UnityEditor.Callbacks;
// BT SO 더블클릭, Editor Open
[OnOpenAsset]
public static bool OnOpenAsset(int instanceId, int line)
{
if (Selection.activeObject is BehaviorTree)
{
OpenWindow();
return true;
}
return false;
}
BT Editor 노드 디자인 가독성 향상
Editor의 Style Seet를 변경
입출력 포트 Horizontal -> Vertical 변경
노드 타입에 따라 CSS클래스 추가. 시각적 스타일을 타입별로 구분
NodeView.uxml 의 Editor 연결
NodeView.uxml 한테 NodeViewStyle.uss 추가 및 재정의
// BehaviorTreeEditor.cs
var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/__Scripts__/__Core__/Behavior Tree/UI Builders/BehaviorTreeEditor.uxml");
// BehaviorTreeEditor.cs
var styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/__Scripts__/__Core__/Behavior Tree/UI Builders/BehaviorTreeEditor.uss");
// BehaviorTreeView.cs
var styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/__Scripts__/__Core__/Behavior Tree/UI Builders/BehaviorTreeEditor.uss");
노드 Undo시 렌더링 오류 :
Undo로 인해 Target Object가 명확하지 않을 때, 인스펙터 GUI를 렌더링 하려고 시도하면 오류가 발생.
=> if(_editor.target) 으로 _editor.OnInspectorGUI 메서드를 호출하기 전에 target이 Null 인지 체크.
노드 위치 변경 되돌리기
노드 생성/삭제 되돌리기
Edge(연결) 생성/삭제 되돌리기
// BehaviorTree.cs
Undo.RecordObject(this, "Behavior Tree (CreateNode)"); // 변경사항 기록(되돌리기 위해)
Undo.RegisterCreatedObjectUndo(node, "BBehavior Tree (CreateNode)"); // 새로 생성된 객체에 대한 Undo 작업 등록.
Undo.RecordObject(this, "Behavior Tree (DeleteNode)");
// AssetDatabase.RemoveObjectFromAsset(node); Undo를 위해 즉시 제거 기능을 주석처리
Undo.DestroyObjectImmediate(node);
{
Undo.RecordObject(root, "Behavior Tree (AddChild)");
root.child = child;
EditorUtility.SetDirty(root, Composite, Decorator);
}
{
Undo.RecordObject(root, "Behavior Tree (RemoveChild)");
root.child = null;
EditorUtility.SetDirty(root, Composite, Decorator);
}
// BehaviorTreeView.cs
Undo.undoRedoPerformed += OnUndoRedo; // 실행 취소가 발생하면 OnUndoRedo 실행 (구독)
}
// 실행 취소시 자동 업데이트를 위해 다시 그리고 저장.
private void OnUndoRedo()
{
PopulateView(_tree);
AssetDatabase.SaveAssets();
// InspectorView.cs
IMGUIContainer container = new IMGUIContainer(() =>
{
if (_editor.target) // Undo로 인해 명확한 target Object 없이 렌더링(GUI Update) 시도시 오류가 발생 하기 때문에 조건문으로 체크
_editor.OnInspectorGUI();
});
// NodeView.cs
using UnityEditor;
Undo.RecordObject(node, "Behavior Tree (Set Position)"); // 노드 위치 변경에 대한 "실행 취소" 작업 기록
EditorUtility.SetDirty(node); // 노드가 변경됨을 에디터에 전달(저장)