using AI.BT; using System; using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEditor.Callbacks; using UnityEditor.Graphs; using UnityEditor.UIElements; using UnityEngine; using UnityEngine.UIElements; public class BlackboardEditor : EditorWindow { [SerializeField] private SerializedObject m_BlackboardObject = null; [SerializeField] private Blackboard m_Blackboard = null; [SerializeField] private ListView m_KeyList = null; [SerializeField] private PropertyField m_SelectedKeyPropertyField = null; [SerializeField] private ToolbarMenu m_AddKeyMenu = null; [MenuItem("Window/UI Toolkit/BlackboardEditor")] public static void Open() { BlackboardEditor wnd = GetWindow<BlackboardEditor>(); wnd.titleContent = new GUIContent("BlackboardEditor"); } public void CreateGUI() { // Each editor window contains a root VisualElement object VisualElement root = rootVisualElement; var visualTreeAsset = BehaviorTreeSettings.GetOrCreateSettings().BlackboardEditorUxml; // Instantiate UXML visualTreeAsset.CloneTree(root); } public static void Open(Blackboard tree) { BlackboardEditor wnd = CreateWindow<BlackboardEditor>(); wnd.titleContent = new GUIContent("BehaviorTreeEditor"); wnd.Initialize(tree); } [OnOpenAsset()] public static bool OpenBehaviorTreeAsset(int instanceID, int line) { var asset_path = AssetDatabase.GetAssetPath(instanceID); if (asset_path != null) { var asset = AssetDatabase.LoadAssetAtPath<Blackboard>(asset_path); if (asset != null) { BlackboardEditor.Open(asset); return true; } } return false; } public void Initialize(Blackboard blackboard) { if (!blackboard) return; m_BlackboardObject = new SerializedObject(blackboard); m_Blackboard = blackboard; m_Blackboard.OnKeyAdded = OnKeyAdded; m_Blackboard.OnKeyRemoved = OnKeyRemoved; rootVisualElement.RegisterCallback<KeyDownEvent>(OnKeyDown); InitKeyMenu(); InitKeyList(); InitSelectedPropertyField(); } private void OnKeyDown(KeyDownEvent evt) { if(evt.keyCode == KeyCode.Delete) { m_Blackboard.Remove(m_KeyList.selectedItem as string); m_SelectedKeyPropertyField.Unbind(); m_KeyList.SetSelection(m_KeyList.itemsSource.Count - 1); evt.StopImmediatePropagation(); } } private void OnKeyRemoved(string obj) { m_KeyList.itemsSource = m_Blackboard.Keys.Keys.ToList(); m_KeyList.RefreshItems(); } private void OnKeyAdded(string obj) { m_KeyList.itemsSource = m_Blackboard.Keys.Keys.ToList(); m_KeyList.RefreshItems(); } private void InitKeyMenu() { m_AddKeyMenu = rootVisualElement.Q<ToolbarMenu>("AddKeyMenu"); m_AddKeyMenu.menu.AppendAction("New Key", action => { m_Blackboard.Add("New Key"); }); } private void InitKeyList() { m_KeyList = rootVisualElement.Q<ListView>("KeyList"); m_KeyList.itemsSource = m_Blackboard.Keys.Keys.ToList(); m_KeyList.makeItem = MakeListItem; m_KeyList.bindItem = BindListItem; m_KeyList.unbindItem = UnBindItem; m_KeyList.selectedIndicesChanged += OnSelectedIndicesChanged; } private void UnBindItem(VisualElement element, int arg2) { var label = ((BlackboardKeyElement)element).m_Label; label.Unbind(); } private void OnSelectedIndicesChanged(IEnumerable<int> enumerable) { if (enumerable.Count() == 0) return; var index = enumerable.First(); if(m_BlackboardObject.FindProperty("_Values").GetArrayElementAtIndex(index) is SerializedProperty property) m_SelectedKeyPropertyField.BindProperty(property); } private void BindListItem(VisualElement element, int index) { var label = ((BlackboardKeyElement)element).m_Label; var key_property = m_BlackboardObject.FindProperty("_Keys"); if (key_property.arraySize == index) return; if (key_property.GetArrayElementAtIndex(index) is SerializedProperty property) { label.BindProperty(property); } } private VisualElement MakeListItem() { return new BlackboardKeyElement(); } private void InitSelectedPropertyField() { m_SelectedKeyPropertyField = rootVisualElement.Q<PropertyField>("SelectedKeyField"); } private void OnSelectionChange() { Blackboard blackboard = Selection.activeObject as Blackboard; if (!blackboard) { return; } if (blackboard && AssetDatabase.CanOpenAssetInEditor(blackboard.GetInstanceID())) { Initialize(blackboard); } } }