void ReplaceNode(EditorData nodeData, Type newType) { BTNode oldNode = nodeData.node; BTNode newNode = CreateNode(newType); // Transfer editor data. newNode.id = nodeData.id; nodeData.node = newNode; // Swap children, then delete old node. if (oldNode is BTDecorator && newNode is BTDecorator) { ((BTDecorator)newNode).child = ((BTDecorator)oldNode).child; ((BTDecorator)oldNode).child = null; } else if (oldNode is BTComposite && newNode is BTComposite) { ((BTComposite)newNode).children = ((BTComposite)oldNode).children; ((BTComposite)oldNode).children = null; } DeleteNode(oldNode, false); // Update parent's reference to the node. if (nodeData.parent) { if (nodeData.parent is BTDecorator) { BTDecorator parentDecorator = (BTDecorator)nodeData.parent; parentDecorator.child = nodeData.node; } else if (nodeData.parent is BTComposite) { BTComposite parentCompositor = (BTComposite)nodeData.parent; parentCompositor.children[nodeData.parentIndex] = nodeData.node; } else { Debug.LogError("Parent node is neither a Decorator nor a Compositor!"); } } else { // Node is root node. _behaviorTree.root = nodeData.node; } // Editor data will have changed, so we must rebuild // it before continuing with rendering the GUI. BuildEditorData(); }
void DrawNodeWindow(int id) { // Get EditorNode EditorData nodeData = _editorData[id]; BTNode node = nodeData.node; Type selectedType = CreateNodeTypeDropdown(node); if (selectedType != node.GetType()) { ReplaceNode(nodeData, selectedType); node = nodeData.node; } if (node is BTComposite) { BTComposite compositor = (BTComposite)node; Rect rect = new Rect(0, 20, _nodeWidth, 20); if (GUI.Button(rect, "Add Child")) { BTNode childNode = CreateNodeWithParent(typeof(BTActionBlank), compositor); compositor.children.Add(childNode); } } else if (node is BTLeaf) { if (node == null) { // Passing null to Editor.CreateEditor() causes the whole editor to hard crash, // so we throw an exception to keep that from happening. node should never be // null in this case, anyway, but if it is we don't want the whole editor to shut down. throw new NullReferenceException(); } Editor editor = Editor.CreateEditor(node); editor.OnInspectorGUI(); } // Drag window last because otherwise you can't click on things GUI.DragWindow(); }
void DrawCompositor(BTComposite compositor) { EditorData nodeData = _editorData[compositor.id]; CreateNodeWindow(nodeData, _nodeWidth, _compositorHeight); for (int index = 0; index < compositor.children.Count; ++index) { BTNode child = compositor.children[index]; EditorData childData = _editorData[child.id]; if (DrawPlusButton(nodeData, childData)) { BTDecorator newChild = (BTDecorator)CreateNodeWithParent(typeof(BTInverter), compositor); newChild.child = child; compositor.children[index] = newChild; _editorData[newChild.id].parentIndex = index; child = newChild; } if (index > 0 && DrawLeftButton(childData)) { SwapCompositorChildren(compositor, index, index - 1); } if (index < compositor.children.Count - 1 && DrawRightButton(childData)) { SwapCompositorChildren(compositor, index, index + 1); } DrawNodeCurve(nodeData.rect, childData.rect, index, compositor.children.Count); DrawNode(child); } }
void SwapCompositorChildren(BTComposite compositor, int firstIndex, int secondIndex) { // Retrieve nodes and editor data. BTNode first = compositor.children[firstIndex]; EditorData childData = _editorData[first.id]; BTNode second = compositor.children[secondIndex]; EditorData secondData = _editorData[second.id]; // Swap the order of the children in the array. compositor.children[secondIndex] = first; compositor.children[firstIndex] = second; // Swap the positions of the two children's nodes. // TODO: Move the entire subtree under each node by the same amount. Vector2 tempPosition = secondData.rect.position; secondData.rect.position = childData.rect.position; childData.rect.position = tempPosition; // Update EditorData indices. secondData.parentIndex = firstIndex; childData.parentIndex = secondIndex; }
void SwapCompositorChildren( BTComposite compositor, int firstIndex, int secondIndex ) { // Retrieve nodes and editor data. BTNode first = compositor.children[firstIndex]; EditorData childData = _editorData[first.id]; BTNode second = compositor.children[secondIndex]; EditorData secondData = _editorData[second.id]; // Swap the order of the children in the array. compositor.children[secondIndex] = first; compositor.children[firstIndex] = second; // Swap the positions of the two children's nodes. // TODO: Move the entire subtree under each node by the same amount. Vector2 tempPosition = secondData.rect.position; secondData.rect.position = childData.rect.position; childData.rect.position = tempPosition; // Update EditorData indices. secondData.parentIndex = firstIndex; childData.parentIndex = secondIndex; }
void DrawCompositor( BTComposite compositor ) { EditorData nodeData = _editorData[compositor.id]; CreateNodeWindow( nodeData, _nodeWidth, _compositorHeight ); for ( int index = 0; index < compositor.children.Count; ++index ) { BTNode child = compositor.children[index]; EditorData childData = _editorData[child.id]; if ( DrawPlusButton( nodeData, childData ) ) { BTDecorator newChild = (BTDecorator)CreateNodeWithParent( typeof( BTInverter ), compositor ); newChild.child = child; compositor.children[index] = newChild; _editorData[newChild.id].parentIndex = index; child = newChild; } if ( index > 0 && DrawLeftButton( childData ) ) { SwapCompositorChildren( compositor, index, index - 1 ); } if ( index < compositor.children.Count - 1 && DrawRightButton( childData ) ) { SwapCompositorChildren( compositor, index, index + 1 ); } DrawNodeCurve( nodeData.rect, childData.rect, index, compositor.children.Count ); DrawNode( child ); } }