Exemplo n.º 1
0
        /// <summary>
        /// Callback to destroy a node.
        /// <param name="node">The node to be destroyed.</param>
        /// </summary>
        void OnDestroyNode(ActionNode node)
        {
            // It's not the Update node?
            if (node != null && !(node is Update))
            {
                ActionStateUtility.DestroyNode(node);
            }

            RegisterEditorOnGUI();
        }
        /// <summary>
        /// Returns action and condition nodes in the supplied nodes; branch nodes are ignored but their hierarchy will be included.
        /// <returns>The actions and conditions in the supplied nodes.</returns>
        /// </summary>
        public static ActionNode[] GetActionsAndConditions(ActionNode[] nodes)
        {
            var actionCondition = new List <ActionNode>();

            if (nodes != null)
            {
                for (int i = 0; i < nodes.Length; i++)
                {
                    if (nodes[i] is BranchNode)
                    {
                        var branch = nodes[i] as BranchNode;
                        actionCondition.AddRange(ActionStateUtility.GetActionsAndConditions(branch.children));
                    }
                    else
                    {
                        actionCondition.Add(nodes[i]);
                    }
                }
            }

            return(actionCondition.ToArray());
        }
Exemplo n.º 3
0
        /// <summary>
        /// Show the node menu.
        /// <param name="node">The target node.</param>
        /// </summary>
        void NodeContextMenu(ActionNode node)
        {
            // Validate Paramenters
            if (node == null)
            {
                return;
            }

            // Create the menu
            var menu = new UnityEditor.GenericMenu();

            // Copy/Cut/Paste/Duplicate
            menu.AddItem(new GUIContent("Copy"), false, delegate() { BehaviourTreeUtility.nodeToPaste = node; });
            menu.AddItem(new GUIContent("Cut"), false, delegate() { BehaviourTreeUtility.nodeToPaste = node; OnDestroyNode(node); });

            ActionNode[] nodesToPaste = ActionStateUtility.GetActionsAndConditions(BehaviourTreeUtility.nodeToPaste != null ? new ActionNode[] { BehaviourTreeUtility.nodeToPaste } : new ActionNode[0]);
            if (nodesToPaste.Length > 0)
            {
                menu.AddItem(new GUIContent("Paste"), false, delegate() { ActionStateUtility.PasteNodes(m_ActionState, nodesToPaste); });
            }
            else
            {
                menu.AddDisabledItem(new GUIContent("Paste"));
            }

            menu.AddItem(new GUIContent("Duplicate"), false, delegate() { ActionStateUtility.PasteNodes(m_ActionState, new ActionNode[] { node }); });

            // Separator
            menu.AddSeparator("");

            // Delete
            menu.AddItem(new GUIContent("Delete"), false, delegate() { this.OnDestroyNode(node); });

            // Show the context menu
            menu.ShowAsContext();
        }
Exemplo n.º 4
0
        /// <summary>
        /// Draws the script details in the gui.
        /// <param name="script">The script to be drawn.</param>
        /// </summary>
        void DrawScriptDetail(Script script)
        {
            GUILayout.BeginVertical(s_Styles.scriptDetailBox);

            // Draw disabled inspector
            if (m_NodeEditor != null && m_SelectedNodeSample != null)
            {
                #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2
                EditorGUIUtility.LookLikeInspector();
                #endif

                // Store gui enabled
                var guiEnabled = GUI.enabled;
                GUI.enabled = false;

                GUILayout.Space(-1f);
                m_NodeEditor.DrawNode(m_SelectedNodeSample);
                GUILayout.Space(8f);

                // Restore gui enabled
                GUI.enabled = guiEnabled;

                #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2
                EditorGUIUtility.LookLikeControls();
                #endif
            }

            // Draws description?
            if (script.description != string.Empty)
            {
                EditorGUILayout.LabelField(string.Empty, "Description: " + script.description, s_Styles.description);
            }

            // Draw parent
            // Update active node
            var activeNode = BehaviourWindow.activeNode;
            UpdateActiveNode(activeNode);

            // Add to a tree
            InternalBehaviourTree activeTree = BehaviourWindow.activeTree;

            if (activeTree != null)
            {
                GUILayout.BeginHorizontal();
                EditorGUILayout.PrefixLabel("Parent");
                if (activeNode != null && m_ActiveNodeType != null)
                {
                    EditorGUILayout.LabelField(new GUIContent(activeNode.name + m_ActiveNodeTypeName, m_ActiveNodeIcon, m_ActiveNodeInfo.description), s_Styles.titleText);
                }
                else
                {
                    EditorGUILayout.LabelField("null", s_Styles.errorLabel);
                }
                GUILayout.EndHorizontal();

                var guiEnabled2  = GUI.enabled;
                var activeBranch = BehaviourWindow.activeNode as BranchNode;
                GUI.enabled = activeTree != null;
                if (GUILayout.Button(activeBranch != null ? "Add as Child of " + activeBranch.name : "Add as Root", GUILayout.ExpandWidth(false)))
                {
                    ActionNode newNode = null;
                    if (activeBranch != null)
                    {
                        newNode = BehaviourTreeUtility.AddNode(activeBranch, script.type);
                    }
                    else
                    {
                        newNode = BehaviourTreeUtility.AddNode(activeTree, script.type);
                    }

                    // Select the new node
                    if (newNode != null)
                    {
                        BehaviourWindow.activeNodeID = newNode.instanceID;
                    }
                }
                GUI.enabled = guiEnabled2;
            }
            else
            {
                // Add to an ActionState
                var actionState = BehaviourWindow.activeState as InternalActionState;

                if (actionState != null && GUILayout.Button("Add Node", GUILayout.ExpandWidth(false)))
                {
                    ActionNode newNode = ActionStateUtility.AddNode(actionState, script.type);
                    // Select the new node
                    if (newNode != null)
                    {
                        BehaviourWindow.activeNodeID = newNode.instanceID;
                    }
                }
            }

            GUILayout.EndVertical();

            GUILayout.Space(18f);

            // Workaround to avoid to close the GUIPropertyField on click
            if (Event.current.type == EventType.Repaint)
            {
                m_LastRect = GUILayoutUtility.GetLastRect();
            }
            if (Event.current.type == EventType.MouseDown && m_LastRect.Contains(Event.current.mousePosition))
            {
                Event.current.Use();
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Unity callback to draw a custom inspector.
        /// </summary>
        public override void OnInspectorGUI()
        {
            // Create styles?
            if (s_Styles == null)
            {
                s_Styles = new InternalActionStateEditor.Styles();
            }

            // Workaround to update nodes
            if (Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed")
            {
                GUIUtility.hotControl      = 0;
                GUIUtility.keyboardControl = 0;
                m_ActionState.LoadNodes();
                UpdateActiveNode();
                return;
            }

            // Reload nodes?
            if (m_ActionState.isDirty)
            {
                m_ActionState.LoadNodes();
                UpdateActiveNode();
            }

            // Register OnGUI node?
            if (!Application.isPlaying && m_ActionState.onGUINode != null && !GUICallback.HasCallbacks())
            {
                this.RegisterEditorOnGUI();
            }

            #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2
            EditorGUIUtility.LookLikeInspector();
            #endif

            // Draw default inspector
            DrawDefaultInspector();

            // Shows the node editor?
            bool showNodeEditor = m_ActionState.parent == null || BehaviourWindow.activeState == m_ActionState;

            // Draw Action List
            if (m_NodeList == null)
            {
                // m_NodeList = new ReorderableList(this.serializedObject, this.serializedObject.FindProperty("m_UpdateActions"));
                m_NodeList = new ReorderableList(m_ActionState.GetNodes(), typeof(ActionNode));
                m_NodeList.drawHeaderCallback  += delegate(Rect rect) { EditorGUI.LabelField(rect, "Nodes"); };
                m_NodeList.drawElementCallback += DrawNode;
                m_NodeList.onAddCallback       += this.OnAddNode;
                m_NodeList.onRemoveCallback    += this.OnRemoveSelectedNode;
                m_NodeList.onSelectCallback    += this.OnSelectNode;
                m_NodeList.onReorderCallback   += this.OnReorderNode;

                // Select the active node
                UpdateActiveNode();

                #if !UNITY_4_0_0 && !UNITY_4_1 && !UNITY_4_2 && !UNITY_4_3
                m_NodeList.list = m_ActionState.GetNodes();
                m_NodeList.DoLayoutList();
                #else
                this.Repaint();
                #endif
            }
            else if (showNodeEditor)
            {
                m_NodeList.list = m_ActionState.GetNodes();
                m_NodeList.DoLayoutList();
            }

            if (showNodeEditor)
            {
                GUILayout.Space(6f);

                #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2
                EditorGUIUtility.LookLikeControls();
                #endif

                // Get the active node
                ActionNode activeNode = m_ActionState.isRoot ? this.GetActiveNode() : BehaviourWindow.activeNode;

                // Draw node properties
                if (m_NodeEditor != null)
                {
                    // Is there an active node?
                    if (activeNode != null && activeNode.owner as InternalActionState == m_ActionState)
                    {
                        // It's an Update node
                        var oldGUIEnabled = GUI.enabled;
                        GUI.enabled = !(activeNode is Update);
                        m_NodeEditor.DrawNode(activeNode);
                        GUI.enabled = oldGUIEnabled;
                        GUILayout.Space(4f);
                    }
                }


                // Copy/Paste/Cut/Duplicate/Delete keyboard shortcuts
                Event current = Event.current;
                if (current.type == EventType.ValidateCommand)
                {
                    // Use event to call event ExecuteCommand
                    if (current.commandName == "Paste")
                    {
                        ActionNode[] nodesToPaste = ActionStateUtility.GetActionsAndConditions(BehaviourTreeUtility.nodeToPaste != null ? new ActionNode[] { BehaviourTreeUtility.nodeToPaste } : new ActionNode[0]);
                        if (nodesToPaste.Length > 0)
                        {
                            current.Use();
                        }
                    }
                    if (activeNode != null)
                    {
                        if (current.commandName == "Copy")
                        {
                            current.Use();
                        }
                        else if (current.commandName == "Duplicate")
                        {
                            current.Use();
                        }
                        else if (current.commandName == "Delete")
                        {
                            current.Use();
                        }
                        else if (current.commandName == "Cut")
                        {
                            current.Use();
                        }
                    }
                }
                else if (Event.current.type == EventType.ExecuteCommand)
                {
                    if (current.commandName == "Paste")
                    {
                        ActionNode[] nodesToPaste = ActionStateUtility.GetActionsAndConditions(BehaviourTreeUtility.nodeToPaste != null ? new ActionNode[] { BehaviourTreeUtility.nodeToPaste } : new ActionNode[0]);
                        ActionStateUtility.PasteNodes(m_ActionState, nodesToPaste);
                    }
                    else if (current.commandName == "Copy")
                    {
                        BehaviourTreeUtility.nodeToPaste = activeNode;
                    }
                    else if (current.commandName == "Duplicate")
                    {
                        ActionStateUtility.PasteNodes(m_ActionState, new ActionNode[] { activeNode });
                    }
                    else if (current.commandName == "Delete")
                    {
                        this.OnDestroyNode(activeNode);
                    }
                    else if (current.commandName == "Cut")
                    {
                        BehaviourTreeUtility.nodeToPaste = activeNode;
                        this.OnDestroyNode(activeNode);
                    }
                }
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Callback to add a new node.
        /// </summary>
        private void OnAddNode(ReorderableList list)
        {
            // Get all node scripts
            var nodeTypes = new List <System.Type>();

            foreach (System.Type type in BehaviourTreeUtility.GetNodeTypes())
            {
                if (!type.IsSubclassOf(typeof(BranchNode)))
                {
                    nodeTypes.Add(type);
                }
            }

            // Create the menu
            var menu = new UnityEditor.GenericMenu();

            // Add node types to the menu
            for (int i = 0; i < nodeTypes.Count; i++)
            {
                var nodeType = nodeTypes[i];
                var nodeInfo = AttributeUtility.GetAttribute <NodeInfoAttribute>(nodeType, false) ?? new NodeInfoAttribute();
                menu.AddItem(new GUIContent(nodeInfo.category + nodeType.Name), false, delegate() { ActionStateUtility.AddNode(m_ActionState, nodeType); RegisterEditorOnGUI(); });
            }

            // Show the context menu
            menu.ShowAsContext();
        }