예제 #1
0
        public void Refresh()
        {
            if (m_needRefresh)
            {
                m_needRefresh = false;

                m_history.Clear();

                if (m_serializedHistory != null)
                {
                    string[] paths = m_serializedHistory.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (var path in paths)
                    {
                        BTAsset asset = AssetDatabase.LoadAssetAtPath <BTAsset>(path);
                        if (asset != null)
                        {
                            m_history.Add(new Brainiac.Tuple <string, BehaviourTree>(path, null));
                        }
                        else
                        {
                            m_history.Clear();
                            break;
                        }
                    }
                }
            }
        }
예제 #2
0
        private void Dispose()
        {
            if (!m_isDisposed)
            {
                if (m_graph != null)
                {
                    BTEditorGraph.DestroyImmediate(m_graph);
                    m_graph = null;
                }
                if (m_btAsset != null)
                {
                    SaveBehaviourTree();
                    m_btAsset.Dispose();
                    m_btAsset = null;
                }

                m_rootTreeAsset = null;

                EditorApplication.playmodeStateChanged -= HandlePlayModeChanged;

                Selection.selectionChanged -= delegate { SetupBTDebugging(); };

                m_isDisposed = true;
            }
        }
예제 #3
0
        private void SetBTAssetDebug(BTAsset asset, BehaviourTree btInstance, bool clearNavigationHistory)
        {
            if (asset != null && btInstance != null && (clearNavigationHistory || asset != m_btAsset || !m_canvas.IsDebuging))
            {
                m_btAsset = asset;
                if (asset is RootTreeAsset)
                {
                    m_rootTreeAsset = asset as RootTreeAsset;
                }

                m_graph.SetBehaviourTree(asset, btInstance);
                m_canvas.Area = m_btAsset.CanvasArea;

                if (Mathf.Approximately(m_btAsset.CanvasPosition.x, 0) && Mathf.Approximately(m_btAsset.CanvasPosition.y, 0))
                {
                    m_canvas.CenterOnPosition(btInstance.Root.Position, position.size);
                }
                else
                {
                    m_canvas.Position = m_btAsset.CanvasPosition;
                }

                m_canvas.IsDebuging = true;

                if (clearNavigationHistory)
                {
                    m_navigationHistory.Clear();
                }

                m_navigationHistory.Push(m_btAsset, btInstance);
            }
        }
예제 #4
0
        private void SetBTAsset(BTAsset asset, bool clearNavigationHistory)
        {
            if (asset != null && (clearNavigationHistory || asset != m_btAsset))
            {
                if (m_btAsset != null)
                {
                    SaveBehaviourTree();
                    m_btAsset.Dispose();
                    m_btAsset = null;
                }

                BehaviourTree behaviourTree = asset.GetEditModeTree();
                if (behaviourTree != null)
                {
                    m_btAsset = asset;
                    m_graph.SetBehaviourTree(behaviourTree);
                    m_canvas.Area = m_btAsset.CanvasArea;
                    m_canvas.CenterOnPosition(behaviourTree.Root.Position, position.size);
                    m_canvas.IsDebuging = false;

                    if (clearNavigationHistory)
                    {
                        m_navigationHistory.Clear();
                    }

                    m_navigationHistory.Push(m_btAsset, null);
                }
                else
                {
                    CrashEditor("Failed to deserialize behaviour tree!\n\nThis can happen when you rename a behaviour node class, when you change the namespace or when you delete a behaviour node script.\n\nTry to enable text serialization and manually edit the asset file to fix the behaviour tree.");
                }
            }
        }
예제 #5
0
        private void AddRecentFile(BTAsset asset)
        {
            string filename = AssetDatabase.GetAssetPath(asset);

            for (int i = 0; i < m_recentFiles.Count; i++)
            {
                if (m_recentFiles[i] == filename)
                {
                    return;
                }
            }

            if (m_recentFiles.Count < MAX_RECENT_FILES)
            {
                m_recentFiles.Add(filename);
            }
            else
            {
                for (int i = 0; i < m_recentFiles.Count - 1; i++)
                {
                    m_recentFiles[i] = m_recentFiles[i + 1];
                }
                m_recentFiles[m_recentFiles.Count - 1] = filename;
            }
        }
예제 #6
0
        protected override void DrawProperties()
        {
            RunBehaviourIndex target = (RunBehaviourIndex)Target;
            bool prevGUIState        = GUI.enabled;

            target.SubTreeIndex = EditorGUILayout.IntField(target.SubTreeIndex);
            EditorGUILayout.Space();

            BTAsset btAsset = BehaviourTreeEditor.GetIndexedSubTreeAsset(target.SubTreeIndex);

            EditorGUILayout.ObjectField("Behaviour Tree", btAsset, typeof(BTAsset), false);
            EditorGUILayout.Space();

            if (BTEditorCanvas.Current.IsDebuging && btAsset != null && target.BehaviourTree != null)
            {
                GUI.enabled = true;
                if (GUILayout.Button("Preview", GUILayout.Height(24.0f)))
                {
                    BehaviourTreeEditor.OpenSubtreeDebug(btAsset, target.BehaviourTree);
                }
            }
            else
            {
                GUI.enabled = btAsset != null;
                if (GUILayout.Button("Open", GUILayout.Height(24.0f)))
                {
                    BehaviourTreeEditor.OpenSubtree(btAsset);
                }
            }

            GUI.enabled = prevGUIState;
        }
예제 #7
0
        public override void OnInspectorGUI()
        {
            LogicObject lo = (LogicObject)target;

            if (EditorApplication.isPlaying)
            {
                if (!lo.ShowAttrs && GUILayout.Button("ShowAttributes"))
                {
                    lo.ShowAttrs = true;
                }
                if (lo.ShowAttrs && GUILayout.Button("HideAttributes"))
                {
                    lo.ShowAttrs = false;
                }
            }
            serializedObject.Update();

            GUI.enabled = !EditorApplication.isPlaying;
            GUI.color   = Color.white;

            serializedObject.ApplyModifiedProperties();
            var agent = lo.so.GetComponent <AIAgent>();

            if (agent != null)
            {
                BTAsset       btAsset    = agent.BehaviourTree as BTAsset;
                BehaviourTree btInstance = agent.GetBehaviourTree();

                GUI.enabled = btAsset != null;
                if (EditorApplication.isPlaying && btInstance != null)
                {
                    if (GUILayout.Button("Preview", GUILayout.Height(24.0f)))
                    {
                        BehaviourTreeEditor.OpenDebug(btAsset, btInstance);
                    }
                }
                else
                {
                    if (GUILayout.Button("Edit", GUILayout.Height(24.0f)))
                    {
                        BehaviourTreeEditor.Open(btAsset);
                    }
                }
            }

            if (m_inspector != null)
            {
                BTEditorStyle.EnsureStyle();
                m_inspector.DrawGUI();
                Repaint();
            }
            else
            {
                EditorGUILayout.HelpBox("There are no values to display!", MessageType.Error);
            }
            GUI.enabled = true;
        }
예제 #8
0
        public static GenericMenu CreateBehaviourTreeEditorMenu(BehaviourTreeEditor editor)
        {
            GenericMenu        menu       = new GenericMenu();
            BTEditorTreeLayout treeLayout = BTEditorStyle.TreeLayout;

            menu.AddItem(new GUIContent("New"), false, editor.CreateNewBehaviourTree);
            menu.AddItem(new GUIContent("Open"), false, editor.OpenBehaviourTree);
            if (BTEditorCanvas.Current.ReadOnly)
            {
                menu.AddDisabledItem(new GUIContent("Save"));
            }
            else
            {
                menu.AddItem(new GUIContent("Save"), false, editor.SaveBehaviourTree);
                AssetDatabase.SaveAssets();
            }

            var recentFiles = editor.NavigationHistory.RecentFiles;

            if (recentFiles.Count > 0)
            {
                GenericMenu.MenuFunction2 func = (obj) =>
                {
                    BTAsset asset = AssetDatabase.LoadAssetAtPath <BTAsset>((string)obj);
                    BehaviourTreeEditor.Open(asset);
                };

                foreach (var file in recentFiles)
                {
                    menu.AddItem(new GUIContent("Recent Files/" + file.Replace('/', '\\')), false, func, file);
                }
            }
            else
            {
                menu.AddItem(new GUIContent("Recent Files/Empty"), false, () => { });
            }

            menu.AddSeparator("");

            menu.AddItem(new GUIContent("Snap To Grid"), BTEditorCanvas.Current.SnapToGrid, () =>
            {
                BTEditorCanvas.Current.SnapToGrid = !BTEditorCanvas.Current.SnapToGrid;
            });

            foreach (BTEditorTreeLayout layout in Enum.GetValues(typeof(BTEditorTreeLayout)))
            {
                menu.AddItem(new GUIContent("Layout/" + layout.ToString()), treeLayout == layout, (obj) =>
                {
                    BTEditorStyle.TreeLayout = (BTEditorTreeLayout)obj;
                }, layout);
            }

            CreateHelpOptions(menu);

            return(menu);
        }
예제 #9
0
        private static bool OnOpenBTAsset(int instanceID, int line)
        {
            BTAsset asset = EditorUtility.InstanceIDToObject(instanceID) as BTAsset;

            if (asset != null)
            {
                Open(asset);
                return(true);
            }

            return(false);
        }
예제 #10
0
        public static void OpenIndexSubtreeDebug(int index, BehaviourTree btInstance)
        {
            BTAsset btAsset = GetIndexedSubTreeAsset(index);

            if (btAsset == null)
            {
                return;
            }
            BehaviourTreeEditor window = EditorWindow.GetWindow <BehaviourTreeEditor>(TitleName());

            window.SetBTAssetDebug(btAsset, btInstance, false);
        }
예제 #11
0
 public void GetAt(int index, out BTAsset asset, out BehaviourTree instance)
 {
     if (index >= 0 && index < m_history.Count)
     {
         asset    = AssetDatabase.LoadAssetAtPath <BTAsset>(m_history[index].Item1);
         instance = m_history[index].Item2;
     }
     else
     {
         asset    = null;
         instance = null;
     }
 }
예제 #12
0
        public void CreateNewBehaviourTree()
        {
            string path = EditorUtility.SaveFilePanelInProject("Create new behaviour tree", "behaviour_tree", "asset", "");

            if (!string.IsNullOrEmpty(path))
            {
                BTAsset asset = ScriptableObject.CreateInstance <BTAsset>();

                AssetDatabase.CreateAsset(asset, path);
                AssetDatabase.Refresh();

                SetBTAsset(AssetDatabase.LoadAssetAtPath <BTAsset>(path), true);
            }
        }
예제 #13
0
        public void Pop(out BTAsset asset, out BehaviourTree instance)
        {
            if (m_history.Count > 0)
            {
                var historyItem = m_history[m_history.Count - 1];
                asset    = AssetDatabase.LoadAssetAtPath <BTAsset>(historyItem.Item1);
                instance = historyItem.Item2;

                m_history.RemoveAt(m_history.Count - 1);
            }
            else
            {
                asset    = null;
                instance = null;
            }
        }
예제 #14
0
        private void DrawNavigationHistory(Rect screenRect)
        {
            EditorGUI.LabelField(screenRect, "", BTEditorStyle.EditorFooter);

            if (m_navigationHistory.Size > 0)
            {
                float left = screenRect.x;
                for (int i = 0; i < m_navigationHistory.Size; i++)
                {
                    BTAsset asset = m_navigationHistory.GetAssetAt(i);
                    if (asset == null)
                    {
                        continue;
                    }
                    GUIStyle style;
                    Vector2  size;

                    if (i > 0)
                    {
                        style = (i == m_navigationHistory.Size - 1) ? BTEditorStyle.BreadcrumbMiddleActive : BTEditorStyle.BreadcrumbMiddle;
                        size  = style.CalcSize(new GUIContent(asset.name));
                    }
                    else
                    {
                        style = (i == m_navigationHistory.Size - 1) ? BTEditorStyle.BreadcrumbLeftActive : BTEditorStyle.BreadcrumbLeft;
                        size  = style.CalcSize(new GUIContent(asset.name));
                    }

                    Rect position = new Rect(left, screenRect.y, size.x, screenRect.height);
                    left += size.x;

                    if (i < m_navigationHistory.Size - 1)
                    {
                        if (GUI.Button(position, asset.name, style))
                        {
                            GoBackInHistory(i);
                            break;
                        }
                    }
                    else
                    {
                        EditorGUI.LabelField(position, asset.name, style);
                    }
                }
            }
        }
예제 #15
0
        public static void Open(BTAsset asset)
        {
            BehaviourTreeEditor window = EditorWindow.GetWindow <BehaviourTreeEditor>(TitleName());

            window.SetBTAsset(asset, true);

            BehaviourTree btInstance;

            if (BTDebugHelper.CheckDebugOpen(asset.TreeUidString, out btInstance))
            {
                window.SetBTAssetDebug(asset, btInstance, true);
            }
            else
            {
                window.SetBTAsset(asset, true);
            }
        }
예제 #16
0
        public void SetBehaviourTree(BTAsset asset, BehaviourTree behaviourTree)
        {
            this.m_asset   = asset;
            this.m_bevTree = behaviourTree;

            if (m_masterRoot != null)
            {
                BTEditorGraphNode.DestroyImmediate(m_masterRoot);
                m_masterRoot = null;
                m_rootStack.Clear();
            }

            m_isBehaviourTreeReadOnly = behaviourTree.ReadOnly;
            m_masterRoot = BTEditorGraphNode.CreateRoot(this, behaviourTree.Root);
            m_rootStack.Push(m_masterRoot);
            BTUndoSystem.Clear();
        }
예제 #17
0
        private void SetBTAssetDebug(BTAsset asset, BehaviourTree btInstance, bool clearNavigationHistory)
        {
            if (asset != null && btInstance != null && (clearNavigationHistory || asset != m_btAsset || !m_canvas.IsDebuging))
            {
                m_btAsset = asset;
                m_graph.SetBehaviourTree(btInstance);
                m_canvas.CenterOnPosition(btInstance.Root.Position, position.size);
                m_canvas.Area       = m_btAsset.CanvasArea;
                m_canvas.IsDebuging = true;

                if (clearNavigationHistory)
                {
                    m_navigationHistory.Clear();
                }

                m_navigationHistory.Push(m_btAsset, btInstance);
            }
        }
예제 #18
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            GUI.enabled = !EditorApplication.isPlaying;
            EditorGUILayout.PropertyField(m_behaviourTree);
            EditorGUILayout.PropertyField(m_body);
            EditorGUILayout.PropertyField(m_updateMode);
            if (m_updateMode.enumValueIndex == (int)UpdateMode.AtInterval)
            {
                EditorGUILayout.PropertyField(m_updateInterval);
            }

            GUI.enabled           = true;
            GUI.color             = m_debugMode.boolValue ? Color.green : Color.red;
            m_debugMode.boolValue = GUILayout.Toggle(m_debugMode.boolValue, "Debug", "Button", GUILayout.Height(24.0f));
            GUI.color             = Color.white;

            serializedObject.ApplyModifiedProperties();

            AIAgent       agent      = (AIAgent)target;
            BTAsset       btAsset    = m_behaviourTree.objectReferenceValue as BTAsset;
            BehaviourTree btInstance = agent.GetBehaviourTree();

            GUI.enabled = btAsset != null;
            if (EditorApplication.isPlaying && btInstance != null)
            {
                if (GUILayout.Button("Preview", GUILayout.Height(24.0f)))
                {
                    BehaviourTreeEditor.OpenDebug(btAsset, btInstance);
                }
            }
            else
            {
                if (GUILayout.Button("Edit", GUILayout.Height(24.0f)))
                {
                    BehaviourTreeEditor.Open(btAsset);
                }
            }

            GUI.enabled = true;
        }
예제 #19
0
        public void OnAfterDeserialize()
        {
            m_history.Clear();

            if (m_serializedHistory != null)
            {
                string[] paths = m_serializedHistory.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (var path in paths)
                {
                    BTAsset asset = AssetDatabase.LoadAssetAtPath <BTAsset>(path);
                    if (asset != null)
                    {
                        m_history.Add(new Tuple <string, BehaviourTree>(path, null));
                    }
                    else
                    {
                        m_history.Clear();
                        break;
                    }
                }
            }

            LoadRecentFiles();
        }
예제 #20
0
 public void Push(BTAsset asset, BehaviourTree instance)
 {
     m_history.Add(new Tuple <string, BehaviourTree>(AssetDatabase.GetAssetPath(asset), instance));
     AddRecentFile(asset);
     SaveRecentFiles();
 }
예제 #21
0
 // Setup links and render nodes
 void Init(BTAsset asset)
 {
     Asset = asset;
     SetupNodes();
     SetupConnectors();
 }
예제 #22
0
 // Open the editor for the given asset
 public static void OpenWindow(BTAsset asset)
 {
     instance = EditorWindow.GetWindow<BTEditor>(asset.ID);
     instance.Init(asset);
 }
예제 #23
0
        public static void OpenSubtree(BTAsset behaviourTree)
        {
            BehaviourTreeEditor window = EditorWindow.GetWindow <BehaviourTreeEditor>(TitleName());

            window.SetBTAsset(behaviourTree, false);
        }
예제 #24
0
        public static void OpenSubtreeDebug(BTAsset btAsset, BehaviourTree btInstance)
        {
            BehaviourTreeEditor window = EditorWindow.GetWindow <BehaviourTreeEditor>(TitleName());

            window.SetBTAssetDebug(btAsset, btInstance, false);
        }
예제 #25
0
        public static void OpenSubtreeDebug(BTAsset btAsset, BehaviourTree btInstance)
        {
            var window = EditorWindow.GetWindow <BehaviourTreeEditor>("Brainiac");

            window.SetBTAssetDebug(btAsset, btInstance, false);
        }
예제 #26
0
        public static void OpenSubtree(BTAsset behaviourTree)
        {
            var window = EditorWindow.GetWindow <BehaviourTreeEditor>("Brainiac");

            window.SetBTAsset(behaviourTree, false);
        }
예제 #27
0
 private void OnEnable()
 {
     m_asset = target as BTAsset;
 }