/// <summary>
        /// Opens the tree in a Bonsai Window.
        /// </summary>
        /// <param name="tree">The tree to open</param>
        /// <returns>
        /// The window that opens the tree. Null if already opened.
        /// </returns>
        public static BonsaiWindow OpenTree(BehaviourTree tree, BonsaiEditor.Mode mode = BonsaiEditor.Mode.Edit)
        {
            if (!tree)
            {
                return(null);
            }

            // Try to find an editor window without a canvas...
            var windows = Resources.FindObjectsOfTypeAll <BonsaiWindow>();

            bool isAlreadyOpened = windows.Any(w => w.Tree == tree);

            if (isAlreadyOpened)
            {
                return(null);
            }

            // Find a window without any tree.
            BonsaiWindow window = windows.FirstOrDefault(w => w.Tree == null);

            // No windows available, make a new one.
            if (!window)
            {
                window = CreateInstance <BonsaiWindow>();
                window.Show();
            }

            window.SetTree(tree, mode);
            return(window);
        }
예제 #2
0
        private void onNodeContextCallback(object o)
        {
            NodeContext context = (NodeContext)o;

            Type nodeType = _selectedNode.behaviour.GetType();

            switch (context)
            {
            case NodeContext.SetAsRoot:
                _window.tree.Root = _selectedNode.behaviour;
                break;

            case NodeContext.Duplicate:
                onNodeCreateCallback(nodeType);
                break;

            case NodeContext.ChangeType:
                // TODO
                BonsaiWindow.LogNotImplemented("Change Type");
                break;

            case NodeContext.Delete:
                _window.editor.canvas.Remove(_selectedNode);
                break;
            }
        }
        private void OpenIncludedSubTree(Standard.Include include)
        {
            if (include.RunningSubTree)
            {
                BonsaiWindow.OpenTree(include.RunningSubTree, Mode.View);
            }

            // Shortcut to open include tree from Include node.
            // Only works in edit mode. View mode is reserved for running tree instances.
            else if (include.subtreeAsset && IsEditMode)
            {
                BonsaiWindow.OpenTree(include.subtreeAsset, Mode.Edit);
            }
        }
        static bool OpenCanvasAsset(int instanceID, int line)
        {
            var          tree = EditorUtility.InstanceIDToObject(instanceID) as BehaviourTree;
            BonsaiWindow w    = OpenTree(tree);

            if (w)
            {
                // If a tree asset was created but has no blackboard, add one upon opening.
                // This is for convenience.
                BonsaiSaver.AddBlackboardIfMissing(tree);

                w.SwitchToViewModeIfRequired();
            }

            return(w);
        }
예제 #5
0
        public BonsaiInputHandler(BonsaiWindow w)
        {
            _window = w;
            _nodeTypeSelectionMenu = new GenericMenu();
            _nodeContextMenu       = new GenericMenu();
            _multiNodeContextMenu  = new GenericMenu();

            // Setup Node Selection menu.
            foreach (var kvp in BonsaiEditor.Behaviours)
            {
                Type nodeType = kvp.Key;
                BonsaiEditor.NodeTypeProperties prop = kvp.Value;

                _nodeTypeSelectionMenu.AddItem(new GUIContent(prop.path), false, onNodeCreateCallback, nodeType);
            }

            // Setup node context menu.
            _nodeContextMenu.AddItem(new GUIContent("Set As Root"), false, onNodeContextCallback, NodeContext.SetAsRoot);
            _nodeContextMenu.AddItem(new GUIContent("Duplicate"), false, onNodeContextCallback, NodeContext.Duplicate);
            _nodeContextMenu.AddItem(new GUIContent("Change Type"), false, onNodeContextCallback, NodeContext.ChangeType);
            _nodeContextMenu.AddItem(new GUIContent("Delete"), false, onNodeContextCallback, NodeContext.Delete);

            // Setup area selection context menu.
            _multiNodeContextMenu.AddItem(new GUIContent("Duplicate"), false, onMultiNodeCallback, NodeContext.DuplicateSelection);
            _multiNodeContextMenu.AddItem(new GUIContent("Delete"), false, onMultiNodeCallback, NodeContext.DeleteSelection);

            // Define the actions to take when a single node is selected.
            onSingleSelected = (node) =>
            {
                // Only apply single node selection on a node that is
                // not currently under area selection.
                if (!node.bAreaSelectionFlag)
                {
                    _window.editor.ClearReferencedNodes();
                    clearAreaSelection();

                    _selectedNode = node;
                    _window.editor.canvas.PushToEnd(_selectedNode);
                    Selection.activeObject = node.behaviour;

                    handleOnAborterSelected(node);
                    handleOnReferenceContainerSelected(node);
                }
            };
        }
예제 #6
0
        void OnEnable()
        {
            _interruptor = target as Interruptor;
            BehaviourTree bt = _interruptor.Tree;

            var editorWindows = Resources.FindObjectsOfTypeAll <BonsaiWindow>();

            // Find the the editor window with the tree associated with this behaviour.
            foreach (BonsaiWindow win in editorWindows)
            {
                // Found the tree, cache this window.
                if (win.tree == bt)
                {
                    parentWindow = win;
                    break;
                }
            }
        }
        private static bool OpenCanvasAsset(int instanceID, int line)
        {
            var treeSelected = EditorUtility.InstanceIDToObject(instanceID) as BehaviourTree;

            if (treeSelected != null)
            {
                BonsaiWindow windowToUse = null;

                // Try to find an editor window without a canvas...
                var bonsaiWindows = Resources.FindObjectsOfTypeAll <BonsaiWindow>();
                foreach (var w in bonsaiWindows)
                {
                    // The canvas is already opened
                    if (w.Tree == treeSelected)
                    {
                        return(false);
                    }

                    // Found a window with no active canvas.
                    if (w.Tree == null)
                    {
                        windowToUse = w;
                        break;
                    }
                }

                // No windows available...just make a new one.
                if (!windowToUse)
                {
                    windowToUse = CreateInstance <BonsaiWindow>();
                    windowToUse.Show();
                }

                // If a tree asset was created but has no blackboard, add one upon opening.
                // This is for convenience.
                BonsaiSaver.AddBlackboardIfMissing(treeSelected);

                windowToUse.SetTree(treeSelected);
                windowToUse.Repaint();
                return(true);
            }

            return(false);
        }
예제 #8
0
        protected virtual void OnEnable()
        {
            var edited = target as BehaviourNode;

            nodeTitle   = serializedObject.FindProperty("title");
            nodeComment = serializedObject.FindProperty("comment");

            // Find the the editor window with the tree associated with this behaviour.
            if (ParentWindow == null)
            {
                ParentWindow = Resources.FindObjectsOfTypeAll <BonsaiWindow>().First(w => w.ContainsNode(edited));

                if (ParentWindow.EditorMode == BonsaiEditor.Mode.View)
                {
                    runtimeHeading = new GUIContent("Runtime values");
                    runtimeFields  = GetRuntimeFields(edited);
                }
            }
        }
예제 #9
0
        private static bool OpenCanvasAsset(int instanceID, int line)
        {
            var treeSelected = EditorUtility.InstanceIDToObject(instanceID) as Core.BehaviourTree;

            if (treeSelected != null)
            {
                BonsaiWindow windowToUse = null;

                // Try to find an editor window without a canvas...
                var bonsaiWindows = Resources.FindObjectsOfTypeAll <BonsaiWindow>();
                foreach (var w in bonsaiWindows)
                {
                    // The canvas is already opened
                    if (w.tree == treeSelected)
                    {
                        return(false);
                    }

                    // Found a window with no active canvas.
                    if (w.tree == null)
                    {
                        windowToUse = w;
                        break;
                    }
                }

                // No windows available...just make a new one.
                if (!windowToUse)
                {
                    windowToUse = EditorWindow.CreateInstance <BonsaiWindow>();
                    windowToUse.titleContent = new GUIContent("Bonsai");
                    windowToUse.Show();
                }

                windowToUse.SetTree(treeSelected);
                windowToUse.saveManager.InitState();
                windowToUse.Repaint();

                return(true);
            }

            return(false);
        }
예제 #10
0
        protected virtual void OnEnable()
        {
            var edited = target as BehaviourNode;

            // Find the the editor window with the tree associated with this behaviour.
            if (ParentWindow == null)
            {
                ParentWindow = Resources.FindObjectsOfTypeAll <BonsaiWindow>().First(w => w.ContainsNode(edited));

                if (ParentWindow.EditorMode == BonsaiEditor.Mode.View)
                {
                    runtimeHeading     = new GUIContent("Runtime values");
                    runtimeHeaderStyle = new GUIStyle {
                        fontSize = 12, fontStyle = FontStyle.Bold
                    };
                    runtimeFields = GetRuntimeFields(edited);
                }
            }
        }
        private void SwitchToViewModeIfRequired()
        {
            // Cannot go to view mode.
            if (!EditorApplication.isPlaying || !Selection.activeGameObject)
            {
                return;
            }

            var           btc        = Selection.activeGameObject.GetComponent <BonsaiTreeComponent>();
            BehaviourTree treeToView = btc ? btc.Tree : null;

            // There must be a non-null tree to view,
            // it must be a different tree than the active tree for this window,
            // and must not be opened somewhere else.
            if (treeToView && Tree != treeToView)
            {
                var windows = Resources.FindObjectsOfTypeAll <BonsaiWindow>();

                bool alreadyInView = windows.Any(w => w.Tree == treeToView);

                if (alreadyInView)
                {
                    return;
                }

                BonsaiWindow window = windows.FirstOrDefault(w => !w.Tree);

                // Have the window without a set tree to view the tree selected.
                if (window)
                {
                    window.SetTree(treeToView, BonsaiEditor.Mode.View);
                }
                else
                {
                    // View tree in this window.
                    SetTree(treeToView, BonsaiEditor.Mode.View);
                }
            }
        }
예제 #12
0
        public BonsaiSaveManager(BonsaiWindow w)
        {
            _window = w;

            _saveFSM = new StateMachine <SaveState>();

            var noTree = new StateMachine <SaveState> .State(SaveState.NoTree);

            var tempTree = new StateMachine <SaveState> .State(SaveState.TempTree);

            var savedTree = new StateMachine <SaveState> .State(SaveState.SavedTree);

            _saveFSM.AddState(noTree);
            _saveFSM.AddState(tempTree);
            _saveFSM.AddState(savedTree);

            // Actions to take when starting out on a window with no canvas.
            _saveFSM.AddTransition(noTree, tempTree, isNewRequested, createNewOnto_Window_WithTempOrEmpty);
            _saveFSM.AddTransition(noTree, savedTree, isLoadRequested, loadOnto_EmptyWindow);

            // Actions to take when the window has a temp canvas.
            _saveFSM.AddTransition(tempTree, tempTree, isNewRequested, createNewOnto_Window_WithTempOrEmpty);
            _saveFSM.AddTransition(tempTree, savedTree, isSaveAsRequested, saveTempAs);
            _saveFSM.AddTransition(tempTree, savedTree, isLoadRequested, loadOnto_Window_WithTempCanvas);

            // Actions to take when the window has a valid canvas (already saved).
            _saveFSM.AddTransition(savedTree, savedTree, isSaveRequested, save);
            _saveFSM.AddTransition(savedTree, savedTree, isSaveAsRequested, saveCloneAs);
            _saveFSM.AddTransition(savedTree, savedTree, isLoadRequested, loadOnto_Window_WithSavedCanvas);
            _saveFSM.AddTransition(savedTree, tempTree, isNewRequested, createNewOnto_Window_WithSavedCanvas);

            // Consume the save operation even after the transition is made.
            _saveFSM.OnStateChangedEvent += () => { _saveOp = SaveOp.None; };

            InitState();
        }