Unity 최종 프로젝트 - 25 (Behavior Tree Editor 제작-3)

이준호·2024년 2월 16일
0
post-custom-banner

📌 Unity 최종 프로젝트



📌 Behavior Tree Graph View Editor 제작

➔ SO Double Click Editor Open

  • BT SO 더블클릭 시 BT Editor Window Open.



Add Code

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;
    }





➔ Editor Style Sheets Improve

  • BT Editor 노드 디자인 가독성 향상

  • Editor의 Style Seet를 변경

    • NodeView.uxml 생성 (노드의 구조 재정의)
      • NodeView class에 성성자(두번째) 를 통해 NodeView.uxml에 연결
      • #selection-border
        • Attibutes
          • Picking Mode -> Ignore
      • Label 추가
        • #node-border -> #contents -> #top -> #title, #output 사이에 description Label 추가
      • #title
        • input, output 사이로 위치 변경
      • #divider (구분선)
        • #description, #output 사이로 위치 변경
    • NodeViewStyle.uss 생성 (노드의 스타일(외관) 재정의) (NodeView.uxml 자식)
      • #node-border (노드 테두리) 추가, 재정의
        • BackGround 색상 변경
        • Border 색상 변경
          • Width, Radius 변경
      • #input
        • Align 가운데 정렬
      • #output
        • Align 가운데 정렬
      • #selection-border
        • Border
          • Color 변경
          • Width 0px
          • Radius 5px
        • Position
          • Absoolute 변경
          • Left , Top, RIght, Bottom -> 0
      • :hover > #selection-border (노드에 마우스가 올라갔을 때)
        • Border
          • Width 1px
      • :selected > #selection-border (노드를 선택(클릭) 했을 때)
        • Border
          • Width 1px
      • :hover:selected > #selection-border (마우스 올리고 선택 시 강조)
        • Border
          • Width 2px
      • .node (모든 노드의 속성 변경 가능)
        • Size
          • Min Width 150px
      • #title
        • Text
          • Font Style -> Bold
          • Size 14
      • #description
        • Text
          • Size -> 10px
      • #divider
        • Size
          • Min Height -> 1px
        • Background
          • Color 변경
      • #(.action, .composite, .decorator, .root) #input
        • Background
          • Color 변경 (coolors.co)
        • (root만 Size Min Height 20px)
    • InputPort, OutputPort 위치 정렬
      • .uss 수정으론 방법이 없어서 NodeView.cs 에서 input, output 의 Port를 생성할때 style.flexDirection을 각각 Column, ColumnReverse 로 설정
  • 입출력 포트 Horizontal -> Vertical 변경

  • 노드 타입에 따라 CSS클래스 추가. 시각적 스타일을 타입별로 구분




Add Code

  • 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");





➔ Editor Node&Edge Undo/Redo

  • 노드 Undo시 렌더링 오류 :
    Undo로 인해 Target Object가 명확하지 않을 때, 인스펙터 GUI를 렌더링 하려고 시도하면 오류가 발생.
    => if(_editor.target) 으로 _editor.OnInspectorGUI 메서드를 호출하기 전에 target이 Null 인지 체크.

  • 노드 위치 변경 되돌리기

  • 노드 생성/삭제 되돌리기

  • Edge(연결) 생성/삭제 되돌리기




Add Code

// 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); // 노드가 변경됨을 에디터에 전달(저장)











📌 출저

TheKiwiCoder

profile
No Easy Day
post-custom-banner

0개의 댓글