/// <summary> /// Updates the nodes order. /// </summary> void UpdateNodes() { var oldNodes = GetNodes(); // Get all root nodes var rootNodes = new List <ActionNode>(); foreach (ActionNode n in oldNodes) { if (n.isRoot) { rootNodes.Add(n); } } var newNodes = new List <ActionNode>(); for (int i = 0; i < rootNodes.Count; i++) { BranchNode branch = rootNodes[i] as BranchNode; if (branch != null) { newNodes.AddRange(branch.GetHierarchy()); } else { newNodes.Add(rootNodes[i]); } } m_Nodes = newNodes.ToArray(); }
/// <summary> /// Returns the branch hierarchy nodes. /// <returns>Tha branch node and all children/subchildren.<returns> /// </summary> public ActionNode[] GetHierarchy() { List <ActionNode> allNodes = new List <ActionNode>() { this }; { var __array1 = this.children; var __arrayLength1 = __array1.Length; for (int __i1 = 0; __i1 < __arrayLength1; ++__i1) { var child = (ActionNode)__array1[__i1]; { BranchNode childBranch = child as BranchNode; if (childBranch != null) { allNodes.AddRange(childBranch.GetHierarchy()); } else { allNodes.Add(child); } } } } return(allNodes.ToArray()); }
/// <summary> /// Removes node from tree. /// <param name="node">The node to be removed.</param> /// <param name="includeHierarchy">If true, the hierarchy will also be removed.</param> /// </summary> public void RemoveNode(ActionNode node, bool includeHierarchy) { GetNodes(); var nodes = new List <ActionNode>(m_Nodes); BranchNode branch = node as BranchNode; // Remove children if (includeHierarchy && branch != null) { foreach (ActionNode n in branch.GetHierarchy()) { nodes.Remove(n); } } // Remove node nodes.Remove(node); m_Nodes = nodes.ToArray(); if (Application.isPlaying && this.enabled) { // Update function nodes m_FunctionNodes = this.GetFunctionNodes(); // Reset status node.ResetStatus(); // Disable node node.OnDisable(); } HierarchyChanged(); }
/// <summary> /// Returns True if the supplied branch is in an ancestor of the node. /// <param name="branch">The branch to test is an ancestor</param> /// <returns>True if the node is in the supplied branch hierarchy; False otherwise.</returns> /// </summary> protected bool IsAncestor (BranchNode branch) { // The branch is not a grandfather for (var grandfather = this.branch; grandfather != null; grandfather = grandfather.branch) { if (grandfather == branch) return true; } return false; }
/// <summary> /// Returns True if the supplied branch is in an ancestor of the node. /// <param name="branch">The branch to test is an ancestor</param> /// <returns>True if the node is in the supplied branch hierarchy; False otherwise.</returns> /// </summary> protected bool IsAncestor(BranchNode branch) { // The branch is not a grandfather for (var grandfather = this.branch; grandfather != null; grandfather = grandfather.branch) { if (grandfather == branch) { return(true); } } return(false); }
/// <summary> /// Returns the branch hierarchy nodes. /// <returns>Tha branch node and all children/subchildren.<returns> /// </summary> public ActionNode[] GetHierarchy() { List <ActionNode> allNodes = new List <ActionNode>() { this }; foreach (ActionNode child in this.children) { BranchNode childBranch = child as BranchNode; if (childBranch != null) { allNodes.AddRange(childBranch.GetHierarchy()); } else { allNodes.Add(child); } } return(allNodes.ToArray()); }
/// <summary> /// Removes node from tree. /// <param name="node">The node to be removed.</param> /// <param name="includeHierarchy">If true, the hierarchy will also be removed.</param> /// </summary> public void RemoveNode(ActionNode node, bool includeHierarchy) { GetNodes(); var nodes = new List <ActionNode>(m_Nodes); BranchNode branch = node as BranchNode; // Remove children if (includeHierarchy && branch != null) { { var __array3 = branch.GetHierarchy(); var __arrayLength3 = __array3.Length; for (int __i3 = 0; __i3 < __arrayLength3; ++__i3) { var n = (ActionNode)__array3[__i3]; { nodes.Remove(n); } } } } // Remove node nodes.Remove(node); m_Nodes = nodes.ToArray(); if (Application.isPlaying && this.enabled) { // Update function nodes m_FunctionNodes = this.GetFunctionNodes(); // Reset status node.ResetStatus(); // Disable node node.OnDisable(); } HierarchyChanged(); }
/// <summary> /// Updates the nodes order. /// </summary> void UpdateNodes() { var oldNodes = GetNodes(); // Get all root nodes var rootNodes = new List <ActionNode>(); { // foreach(var n in oldNodes) var __enumerator1 = (oldNodes).GetEnumerator(); while (__enumerator1.MoveNext()) { var n = (ActionNode)__enumerator1.Current; { if (n.isRoot) { rootNodes.Add(n); } } } } var newNodes = new List <ActionNode>(); for (int i = 0; i < rootNodes.Count; i++) { BranchNode branch = rootNodes[i] as BranchNode; if (branch != null) { newNodes.AddRange(branch.GetHierarchy()); } else { newNodes.Add(rootNodes[i]); } } m_Nodes = newNodes.ToArray(); }
/// <summary> /// Sets a new drop and/or insertion. Changes the drag and drop logic. /// <returns>True if the drop target has changed; false otherwise.</returns> /// </summary> public bool SetDrop (ActionNode drop, bool insertion) { if (m_Drop != drop || (insertion && m_Insertion != drop) || (!insertion && m_Insertion != null)) { if (insertion) { m_Insertion = drop; m_Drop = drop.branch; } else { m_Drop = drop as BranchNode; m_Insertion = null; } return true; } return false; }
/// <summary> /// Callback to create a new child node. /// <param name="type">The new node type.</param> /// <param name="branch">The branch of the new node; or null if its a root node.</param> /// </summary> void OnAddNewNode (System.Type type, BranchNode branch) { ActionNode newNode = null; InternalBehaviourTree activeTree = BehaviourWindow.activeTree; // Add node if (branch != null) newNode = BehaviourTreeUtility.AddNode(branch, type); else if (activeTree != null) newNode = BehaviourTreeUtility.AddNode(activeTree, type); if (newNode != null) { // Is the new node a child of the branch? if (branch != null && newNode.branch == branch) SetExpanded(branch.instanceID, true); // Expand branch // Select newNode BehaviourWindow.activeNodeID = newNode.instanceID; // Update data Refresh(); } }
/// <summary> /// Callback to paste a node. /// <param name="parent">The parent node to be pasted or null to paste as a root node.</param> /// </summary> void OnPasteNode (BranchNode parent) { var newNode = BehaviourTreeUtility.PasteNode(BehaviourWindow.activeTree, parent); if (newNode != null) { // Select newNode BehaviourWindow.activeNodeID = newNode.instanceID; // Update data Refresh(); } }
/// <summary> /// Callback to remove a branch. /// <param name="branch">The target branch to be removed.</param> /// </summary> void OnRemoveBranch (BranchNode branch) { if (branch != null && BehaviourTreeUtility.RemoveBranch(branch)) { // Forces node selection update BehaviourWindow.activeNodeID = 0; // Removes branch from expanded list if (m_Expanded.Contains(branch.instanceID)) SetExpanded(branch.instanceID, false); Refresh(); } }
/// <summary> /// Updates current node by incremeting m_CurrentNodeIndex). /// </summary> void GoToNextNode () { m_CurrentNodeIndex++; if (m_CurrentNodeIndex >= 0 && m_CurrentNodeIndex < m_Nodes.Count) { m_CurrentNode = m_Nodes[m_CurrentNodeIndex]; m_CurrentBranch = m_CurrentNode as BranchNode; m_CurrentFunction = m_CurrentBranch != null ? m_CurrentBranch as FunctionNode : null; } else { m_CurrentNode = null; m_CurrentBranch = null; m_CurrentFunction = null; m_CurrentNodeIndex = -1; m_IsValid = false; } }
/// <summary> /// Remove the suplied branch from the tree. /// <param name="branch">The node to be removed.</param> /// <returns>True if the node was successfully removed; false otherwise.</returns> /// </summary> public static bool RemoveBranch (BranchNode branch) { // The Branch is not a decorator if (branch != null && branch.tree != null) { // Gets parent's children and node's id var parent = branch.branch; ActionNode[] children = branch.children; var tree = branch.tree; // The parent is a decorator or null (node is root) and the branch has more than one child? if (children.Length >= 2 && (parent == null || parent is DecoratorNode) || parent == null) { EditorApplication.Beep(); return false; } // Register Undo #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 Undo.RegisterUndo(branch.tree, "Remove Branch"); #else Undo.RecordObject(branch.tree, "Remove Branch"); #endif // Removes children from branch and adds to parent if (parent != null) { // Get the branch index int branchIndex = (new List<ActionNode>(parent.children)).IndexOf(branch); parent.Remove(branch); for (int i = 0; i < children.Length; i++) { branch.Remove(children[i]); parent.Insert(branchIndex++, children[i]); } // Call OnValidate on the parent parent.OnValidate(); } // Removes node from tree tree.RemoveNode(branch, false); // Saves tree and marks dirty flag StateUtility.SetDirty(tree); return true; } return false; }
/// <summary> /// Paste the node in BehaviourTreeUtility.nodeToPaste in the supplied tree. /// <param name="tree">The target tree.</param> /// <param name="parent">Optional parent to paste the node; or null to paste as a root node.</param> /// <returns>The pasted node.</returns> /// </summary> public static ActionNode PasteNode (InternalBehaviourTree tree, BranchNode parent = null) { // Get the node to be pasted var node = BehaviourTreeUtility.nodeToPaste; // Validate parameters if (node != null && tree != null) { // Register Undo #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 Undo.RegisterUndo(tree,"Paste Node"); #else Undo.RecordObject(tree,"Paste Node"); #endif var newNode = node.Copy(tree); if (newNode != null) { // Add to parent branch? if (parent != null) { parent.Add(newNode); // Call OnValidate on the parent parent.OnValidate(); } // Saves node and sets dirty flag StateUtility.SetDirty(tree); // Reload tree to update variables tree.LoadNodes(); } return newNode; } return null; }
/// <summary> /// Inserts a new node to the supplied branch, automatically handles undo, dirty flag and save node. /// <param name="node">The branch to add a new node.</param> /// <param name="newNodePosition">Move the node to the position of this node.</param> /// <param name="branch">The branch to drop the node or null.</param> /// </summary> public static bool MoveNode (ActionNode node, ActionNode newNodePosition, BranchNode branch) { // Validate parameters if (node != null && node.tree != null) { // Get the tree var tree = node.tree; // The node does not belongs to the tree? if (!tree.GetNodes().Contains(node)) return false; // Register Undo #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 Undo.RegisterUndo(tree,"Move Node"); #else Undo.RecordObject(tree,"Move Node"); #endif // The node will be a root node? if (branch == null) { // Remove from old branch if (node.branch != null) { BranchNode oldBranch = node.branch; node.branch.Remove(node); // Call OnValidate on old branch oldBranch.OnValidate(); } if (newNodePosition == null) { var newIndex = node.tree.GetNodes().Count - 1; node.tree.MoveNode(node.GetIndex(), newIndex); } else { var newIndex = newNodePosition.root.GetIndex(); node.tree.MoveNode(node.GetIndex(), newIndex); } } // The new node position is null? else if (newNodePosition == null) { // node.branch = branch; // Store old branch var oldBranch = node.branch; // Remove from old branch if (oldBranch != null) { oldBranch.Remove(node); } // Add to drop if (!branch.Add(node)) { // Restore old branch if (oldBranch != null) oldBranch.Add(node); return false; } // Call OnValidate on branches branch.OnValidate(); if (oldBranch != null && oldBranch != branch) oldBranch.OnValidate(); node.tree.HierarchyChanged(); } else { // Cache the oldBranch BranchNode oldBranch = node.branch; // Get index var index = -1; var children = branch.children; for (int i = 0; i < children.Length; i++) { if (children[i] == newNodePosition) { index = i; break; } } // The index is invalid? if (index < 0 || !branch.Insert(index, node)) { return false; } else { // Call OnValidate on the branches if (oldBranch != null) oldBranch.OnValidate(); branch.OnValidate(); node.tree.HierarchyChanged(); } } // Save move opration StateUtility.SetDirty(tree); return true; } return false; }
/// <summary> /// Inserts a new node to the supplied branch, automatically handles undo, dirty flag and save node. /// <param name="branch">The branch to add a new node.</param> /// <param name="index">The index of the new node.</param> /// <param name="nodeType">The type of the new node.</param> /// <returns>The new node.</returns> /// </summary> public static ActionNode InsertNode (BranchNode branch, int index, System.Type nodeType) { // Validate parameters if (branch != null && branch.tree != null && nodeType != null && index >= 0 && index <= branch.children.Length) { // Get the tree var tree = branch.tree; // Register Undo #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 Undo.RegisterUndo(tree,"Insert New Node"); #else Undo.RecordObject(tree,"Insert New Node"); #endif // Create new node var newNode = tree.AddNode(nodeType); if (newNode != null) { // Insert new node branch.Insert(index, newNode); // Call OnValidate on the parent branch.OnValidate(); // Saves node and sets dirty flag StateUtility.SetDirty(tree); return newNode; } } return null; }
/// <summary> /// Adds a new node to the parent, automatically handles undo, dirty flag and save node. /// <param name="parent">The branch to add the child.</param> /// <param name="childType">The type of the new node.</param> /// <returns>The new node.</returns> /// </summary> public static ActionNode AddNode (BranchNode parent, System.Type childType) { // Validate parameters if (parent != null && parent.tree != null && childType != null) { // Register Undo #if UNITY_4_0_0 || UNITY_4_1 || UNITY_4_2 Undo.RegisterUndo(parent.tree,"Add New Node"); #else Undo.RecordObject(parent.tree,"Add New Node"); #endif var newNode = parent.tree.AddNode(childType); if (newNode != null) { // Adds new node as child of parent parent.Add(newNode); // Call OnValidate on the parent parent.OnValidate(); // Saves node and sets dirty flag StateUtility.SetDirty(parent.tree); return newNode; } } return null; }
/// <summary> /// Reset the logic to the default values. /// </summary> public void Reset () { m_Target = null; m_Drop = null; m_Insertion = null; m_MonoScript = null; }
/// <summary> /// Reset members. /// </summary> public void Reset () { if (m_Tree != null) m_Nodes = m_Tree.GetNodes(); else m_Nodes = new List<ActionNode>(); m_CurrentNode = null; m_CurrentBranch = null; m_CurrentFunction = null; m_CurrentNodeIndex = -1; m_IsValid = true; }
int CountNodesInBranch (BranchNode branch) { var n = 0; foreach (var child in branch.children) { n++; if (child is BranchNode) n += CountNodesInBranch(child as BranchNode); } return n; }