void OnEnable() { BTAsset btAsset = serializedObject.targetObject as BTAsset; BTEditorManager.RefreshNodeTypes(); BTEditorManager.Refresh(btAsset); }
public override void OnInspectorGUI() { if (BTEditorManager.SelectTree != null) { if (BTEditorManager.SelectTree.nodeDic.Count > 2) { EditorGUILayout.LabelField(string.Format("{0} nodes", BTEditorManager.SelectTree.nodeDic.Count - 1), TitleStyle); } else if (BTEditorManager.SelectTree.nodeDic.Count == 2) { EditorGUILayout.LabelField("Empty", TitleStyle); } else { EditorGUILayout.LabelField("1 node", TitleStyle); } } EditorGUILayout.Space(); if (GUILayout.Button("Show Behavior Tree editor")) { BTEditorWindow.ShowWindow(); } if (GUI.changed) { BTEditorManager.Dirty(); } }
private void DragNodes(List <int> nodes) { if (Application.isPlaying || nodes.Count <= 0) { return; } Vector2 step = GetDragStep(); // 只有单节点时才允许连带子节点移动 BTNode tempNode = null; if (nodes.Count == 1 && Event.current.shift) { tempNode = BTEditorManager.GetNodeByID(nodes[0]); DragWithChildren(tempNode, step); } else { // 只移动选中的节点 foreach (var nodeID in nodes) { tempNode = BTEditorManager.GetNodeByID(nodeID); if (tempNode == null) { continue; } tempNode.editorPosition += step; } } mMouseStartPos += step; }
void DrawConnectionLine() { if (mSelectedNodes.Count < 0) { return; } BTNode contextNode = BTEditorManager.GetNodeByID(mSelectedNodes[0]); if (contextNode == null) { return; } Vector3 startPos = Vector3.zero; Vector3 startTan = Vector3.zero; Vector2 mousePos = Event.current.mousePosition; Vector3 endPos = new Vector3(mousePos.x, mousePos.y, 0); Vector3 endTan = Vector3.zero; if (mCurMode == Mode.ConnectParent) { startPos = new Vector3(contextNode.editorPosition.x + (NodeRenderer.Width / 2), contextNode.editorPosition.y, 0); startTan = startPos + Vector3.down * GridRenderer.step.x * 2; endTan = endPos + Vector3.up * GridRenderer.step.x * 2; } else if (mCurMode == Mode.ConnectChild) { startPos = new Vector3(contextNode.editorPosition.x + (NodeRenderer.Width / 2), contextNode.editorPosition.y + NodeRenderer.Height, 0); startTan = startPos + Vector3.up * GridRenderer.step.x * 2; endTan = endPos + Vector3.down * GridRenderer.step.x * 2; } Handles.DrawBezier(startPos, endPos, startTan, endTan, Color.white, null, 4); }
// Context Menu actions public void Add(object userData) { MenuAction menuAction = userData as MenuAction; int parentID = -1; if (menuAction.nodeIDs != null) { parentID = menuAction.nodeIDs[0]; } BTEditorManager.Add(parentID, menuAction.position, menuAction.nodeType); }
public static void Connect(int parentID, int childID) { BTNode parent = BTEditorManager.GetNodeByID(parentID); BTNode child = BTEditorManager.GetNodeByID(childID); if (parent != null && parent.CanConnectChild && child != null) { parent.ConnectChild(child); // SortChildren(parent); Dirty(); } else { Debug.LogWarning(string.Format("{0} can't accept child {1}", parent, child)); } }
public override void OnInspectorGUI() { serializedObject.Update(); BTNode node = serializedObject.targetObject as BTNode; DrawInspector(node); base.DrawDefaultInspector(); if (GUI.changed) { BTEditorManager.Dirty(); } serializedObject.ApplyModifiedProperties(); }
private void RefreshSelection() { if (mSelectedNodes == null) { return; } int count = mSelectedNodes.Count; UnityEngine.Object[] nodeArray = new UnityEngine.Object[count]; for (int i = 0; i < count; ++i) { nodeArray[i] = BTEditorManager.GetNodeByID(mSelectedNodes[i]); } Selection.objects = nodeArray; }
/// <summary> /// 保存行为树到xml文件,并生成对应lua文件 /// </summary> /// <param name="userData"></param> public void Save(object userData) { // 序列化 BTEditorManager.SelectAsset.Serialize(BTEditorManager.SelectTree); // 存储到文件 string file = Application.dataPath.Replace("Assets", "") + BTEditorManager.SelectAsset.SerializeToFile(); BTEditorManager.ConvertFileFromXMLToLua(file); // 生成AI加载列表 AIMenuEditor.GenerateAILoadList(); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); Debug.Log("保存结束"); }
// Returns true if needs a repaint void HandleMouseEvents(Rect position, Dictionary <int, BTNode> nodeDic) { Event e = Event.current; // MouseDown // // Identify the control being clicked if (Event.current.type == EventType.MouseDown) { // Do nothing for MouseDown on the scrollbar, if present if (e.mousePosition.x >= position.width + mScrollPoint.x || e.mousePosition.y >= position.height + mScrollPoint.y) { mCurMode = Mode.None; } // MouseDown in the canvas, check if in a node or on background else { // Store the mouse position mMouseStartPos = e.mousePosition; // Loop through nodes and check if their rects contain the mouse position BTNode contextNode = null; BTNode tempNode = null; foreach (var kvp in nodeDic) { tempNode = kvp.Value; if (tempNode != null && mNodeRenderer.rectForNode(tempNode).Contains(mMouseStartPos)) { // Connect a parent to a child if (mCurMode == Mode.ConnectChild) { BTEditorManager.Connect(owner.connectOrigin, tempNode.GetInstanceID()); // editorWindow.wantsMouseMove = false; mCurMode = Mode.None; break; } // Connect a child to a parent else if (mCurMode == Mode.ConnectParent) { BTEditorManager.Connect(tempNode.GetInstanceID(), owner.connectOrigin); // editorWindow.wantsMouseMove = false; mCurMode = Mode.None; break; } // Perform a node action at key up else { mCurMode = Mode.NodeAction; contextNode = tempNode; } } } // Cancel the connection if (mCurMode == Mode.ConnectParent || mCurMode == Mode.ConnectChild) { // editorWindow.wantsMouseMove = false; mCurMode = Mode.None; } // MouseDown on the canvas background enables panning the view if (mCurMode == Mode.None && contextNode == null) { mCurMode = Mode.CanvasAction; } SelectNode(contextNode); } return; } // Mouse Up // // MouseUp resets the current interaction mode to None if (e.type == EventType.MouseUp) { mPickingup = false; // Context Menu if (IsRightMouseBtn()) { if (mCurMode == Mode.NodeAction) { owner.ShowContextMenu(e.mousePosition, EditorZoomArea.GetScrollOffset(zoomScale, mScrollPoint), mSelectedNodes); } else if (mCurMode == Mode.CanvasAction) { owner.ShowContextMenu(e.mousePosition, EditorZoomArea.GetScrollOffset(zoomScale, mScrollPoint), null); } } // Resize canvas after a drag else if (mCurMode == Mode.DragNode) { BTEditorManager.Dirty(); } mCurMode = Mode.None; return; } // Mouse Drag // if (e.type == EventType.MouseDrag) { if (IsLeftMouseBtn()) { if (mCurMode == Mode.CanvasAction) { if (e.modifiers == EventModifiers.Alt) { mPickingup = true; mPickupStartPos = mMouseStartPos; } else if (e.modifiers == EventModifiers.None) { mScrollPoint -= (e.delta / zoomScale); } } // Switch to node dragging mode else if (mCurMode == Mode.NodeAction) { if (mSelectedNodes.Count > 0 && e.modifiers != EventModifiers.Control) { Vector2 mousePos = e.mousePosition; float deltaX = Mathf.Abs(mousePos.x - mMouseStartPos.x); float deltaY = Mathf.Abs(mousePos.y - mMouseStartPos.y); // Ignore mouse drags inside nodes lesser than the grid step. These would be rounded, // and make selecting a node slightly more difficult. if (deltaX >= GridRenderer.step.x || deltaY >= GridRenderer.step.y) { mCurMode = Mode.DragNode; } } } // Drag a node if (mCurMode == Mode.DragNode) { // 距离Node中心位置的移动距离 DragNodes(mSelectedNodes); } } return; } // 鼠标移出窗口 if (e.type == EventType.MouseLeaveWindow) { if (mPickingup) { mPickingup = false; } return; } // Zoom if (e.type == EventType.ScrollWheel) { if (e.modifiers == EventModifiers.Alt) { Vector2 delta = e.delta; float zoomDelta = -delta.y / 150.0f; zoomScale += zoomDelta; zoomScale = Mathf.Clamp(zoomScale, ZoomMin, ZoomMax); e.Use(); } return; } // 按键操作 if (e.type == EventType.KeyDown) { if (e.control) { // 复制 if (e.keyCode == KeyCode.C) { BTEditorManager.Copy(mSelectedNodes.ToArray()); return; } // 粘贴 if (e.keyCode == KeyCode.V) { Vector2 to = BTEditorManager.CopyFromPos; to.x += 100f; BTEditorManager.Paste(to); return; } } // 删除 if (e.keyCode == KeyCode.Delete) { BTEditorManager.Delete(mSelectedNodes.ToArray()); return; } } }
public void Paste(object userData) { MenuAction menuAction = userData as MenuAction; BTEditorManager.Paste(menuAction.position); }
public void Copy(object userData) { MenuAction menuAction = userData as MenuAction; BTEditorManager.Copy(menuAction.nodeIDs.ToArray()); }
public void Unparent(object userData) { MenuAction menuAction = userData as MenuAction; BTEditorManager.Unparent(menuAction.nodeIDs[0]); }
public void ShowContextMenu(Vector2 mousePos, Vector2 offset, List <int> nodeList) { if (Application.isPlaying) { return; } var menu = new GenericMenu(); if (nodeList != null && nodeList.Count > 0) { if (nodeList.Count == 1) { BTNode node = BTEditorManager.GetNodeByID(nodeList[0]); // 添加 if (node.CanConnectChild) { foreach (var kvp in mAddContextDic) { menu.AddItem(new GUIContent("Add Child/" + kvp.Key), false, Add, new MenuAction(nodeList, mousePos, kvp.Value)); } } else { menu.AddDisabledItem(new GUIContent("Add")); } // Connect/Disconnect Parent menu.AddSeparator(""); if (!(node is BaseRoot) && !(node is Root)) { if (node.parent != null) { menu.AddItem(new GUIContent("Disconnect from Parent"), false, Unparent, new MenuAction(nodeList)); } else { menu.AddItem(new GUIContent("Connect to Parent"), false, ConnectParent, new MenuAction(nodeList)); } } // Connect Child menu.AddSeparator(""); if (node.CanConnectChild) { menu.AddItem(new GUIContent("Connect to Child"), false, ConnectChild, new MenuAction(nodeList)); } else { menu.AddDisabledItem(new GUIContent("Connect to Child")); } // Copy menu.AddSeparator(""); menu.AddItem(new GUIContent("Copy"), false, Copy, new MenuAction(nodeList, mousePos)); // Delete menu.AddSeparator(""); menu.AddItem(new GUIContent("Delete"), false, Delete, new MenuAction(nodeList)); } else { // Copy menu.AddSeparator(""); menu.AddItem(new GUIContent("Copy"), false, Copy, new MenuAction(nodeList, mousePos)); // Delete menu.AddSeparator(""); menu.AddItem(new GUIContent("Delete"), false, Delete, new MenuAction(nodeList)); } } // 右键点击画布 else { // 添加 foreach (var kvp in mAddContextDic) { menu.AddItem(new GUIContent("Add/" + kvp.Key), false, Add, new MenuAction(nodeList, mousePos, kvp.Value)); } // 粘贴 menu.AddSeparator(""); if (BTEditorManager.CopyFromNodes.Count > 0) { menu.AddItem(new GUIContent("Paste"), false, Paste, new MenuAction(null, mousePos)); } else { menu.AddDisabledItem(new GUIContent("Paste")); } // 保存 menu.AddSeparator(""); menu.AddItem(new GUIContent("Save"), false, Save, null); } menu.DropDown(new Rect(mousePos + offset, Vector2.zero)); }