public static BtNodeType CreateNodeType(BtNode node) { var key = node.NodeName; if (key == BtConst.RootName) { return(new Root(node)); } if (mNodeTypeDict.ContainsKey(key)) { var type = mNodeTypeDict[key]; switch (type) { case "actions": return(new Task(node)); case "composites": return(new Composite(node)); case "decorators": return(new Decorator(node)); } } throw new ArgumentNullException(node.NodeName, "找不到该节点"); }
public static GenericMenu GetGenericMenu(BtNode node, GenericMenu.MenuFunction2 callback) { var menu = new GenericMenu(); if (!node.IsTask && node.ChildNodeList.Count < node.Type.CanAddNodeCount) { foreach (var kv in mNodeTypeDict) { var data = kv.Key.Replace("Node", ""); var menuPath = $"{kv.Value}/{data}"; menu.AddItem(new GUIContent(menuPath), false, callback, kv.Key); } if (BtEditorWindow.CopyNode != null) { menu.AddSeparator(""); menu.AddItem(new GUIContent("Paste Node"), false, callback, "Paste"); } } if (!node.IsRoot) { menu.AddSeparator(""); menu.AddItem(new GUIContent("Copy Node"), false, callback, "Copy"); menu.AddItem(new GUIContent("Delete Node"), false, callback, "Delete"); } return(menu); }
public static void WalkNodeData(BtNode parent) { parent.Data.name = parent.NodeName; parent.Data.SetPosition(parent.BtNodeGraph.RealRect.position); if (parent.IsHaveChild) { foreach (var node in parent.ChildNodeList) { WalkNodeData(node); } parent.Data.children.Sort((a, b) => { if (a.posX > b.posX) { return(1); } if (a.posX < b.posX) { return(-1); } if (a.posY > b.posY) { return(1); } if (a.posY < b.posY) { return(-1); } return(0); }); } }
public static BtNode PasteChild(BehaviourTree owner, BtNode parent, float x, float y) { var nodeData = BtEditorWindow.CopyNode.Data.Clone(); nodeData.SetPos(x, y); parent.Data.AddChild(nodeData); return(AddChildNode(owner, parent, nodeData)); }
public static BtNode AddChildNode(BehaviourTree owner, BtNode parent, BtNodeData data) { data.SetPosition(owner.GenNodePos(data.GetPosition())); //避免重叠 var child = new BtNode(owner, parent, data); owner.AddNode(child); parent.ChildNodeList.Add(child); return(child); }
private void UpdateNodePosition(BtNode parent, Vector2 delta) { parent.BtNodeGraph.RealRect.position += delta; if (parent.IsHaveChild) { foreach (var node in parent.ChildNodeList) { UpdateNodePosition(node, delta); } } }
private void SetNodePosition(BtNode parent) { BtHelper.AutoAlignPosition(parent); if (parent.IsHaveChild) { foreach (var node in parent.ChildNodeList) { SetNodePosition(node); } } }
public static void AutoAlignPosition(BtNode node) { var width = (BtConst.DefaultWidth + BtConst.DefaultSpacingX) / 2; var multiW = Mathf.RoundToInt(node.BtNodeGraph.RealRect.x / width); float x = multiW * width; var height = (BtConst.DefaultHeight + BtConst.DefaultSpacingY) / 2; var multiH = Mathf.RoundToInt(node.BtNodeGraph.RealRect.y / height); float y = multiH * height; node.BtNodeGraph.RealRect.position = new Vector2(x, y); }
public BtNode(BehaviourTree owner, BtNode parent, BtNodeData data) { Owner = owner; Parent = parent; Data = data; BtNodeGraph = new BtNodeGraph(); NodeName = data.name; BtNodeGraph.RealRect = new Rect(data.posX, data.posY, BtConst.DefaultWidth, BtConst.DefaultHeight); ChildNodeList = new List <BtNode>(); Guid = BtHelper.GenerateUniqueStringId(); Type = BtHelper.CreateNodeType(this); }
public static void WalkJsonData(BehaviourTree owner, BtNode parent) { var childrenData = parent.Data.children; if (childrenData != null && childrenData.Count > 0) { foreach (var data in childrenData) { var child = AddChildNode(owner, parent, data); WalkJsonData(owner, child); } } }
public static BtNode AddChildNode(BehaviourTree owner, BtNode parent, string name) { var pos = parent.BtNodeGraph.RealRect.position; if (!mNodeTypeDict.ContainsKey(name)) { throw new ArgumentNullException(name, "找不到该类型"); } var data = new BtNodeData(name, mNodeTypeDict[name], pos.x, pos.y + BtConst.DefaultHeight + BtConst.DefaultSpacingY); parent.Data.AddChild(data); return(AddChildNode(owner, parent, data)); }
public void AddNode(BtNode node) { NodeDict.Add(node.Guid, node); //用于判断是否重叠 var key = node.Data.GetPosition().ToString(); if (NodePosDict.TryGetValue(key, out var count)) { NodePosDict[key] = count + 1; } else { NodePosDict.Add(key, 1); } }
public BehaviourTree(string name, BtNodeData data = null) { Name = name; NodeDict = new Dictionary <string, BtNode>(); NodePosDict = new Dictionary <string, int>(); BrokenNodeDict = new Dictionary <string, BtNode>(); if (data == null) { data = new BtNodeData(BtConst.RootName, null, (BtEditorWindow.Window.position.width - BtConst.RightInspectWidth) / 2, 50); data.AddData("restart", "1"); } Root = new BtNode(this, null, data); AddNode(Root); BtHelper.AutoAlignPosition(Root); }
public static void RemoveChild(BtNode node) { if (node.IsHaveChild) { foreach (var child in node.ChildNodeList) { child.Owner.AddBrokenNode(child); child.Parent = null; } } if (node.IsHaveParent) { node.Parent.ChildNodeList.Remove(node); node.Parent.Data.children.Remove(node.Data); } node.Owner.RemoveNode(node); }
public static void SetNodeDefaultData(BtNode node, string name) { var data = node.Data; var options = nodeOptions; if (options.TryGetValue(name, out var option)) { foreach (var kv in option) { if (kv.Key == "displayName") { data.displayName = kv.Value; } else { data.AddData(kv.Key, kv.Value); } } } }
public Composite(BtNode node) : base(node) { }
public void AddBrokenNode(BtNode node) { BrokenNodeDict.Add(node.Guid, node); }
/// <summary> /// 处理事件 /// </summary> private void DealHandles(Rect canvas) { var window = BtEditorWindow.Window; var curEvent = window.Event; if (curEvent.type == EventType.MouseDrag && curEvent.button == 0) { //拖拽 if (BtNodeGraph.NodeRect.Contains(curEvent.mousePosition) && mCanDragMove) { curEvent.Use(); mIsDragging = true; window.CurSelectNode = this; var delta = BtEditorWindow.IsLockAxisY ? new Vector2(curEvent.delta.x, 0) : curEvent.delta; UpdateNodePosition(this, delta); } } else if (curEvent.type == EventType.MouseDown && curEvent.button == 0) { //点击 if (curEvent.mousePosition.x >= canvas.width - BtConst.RightInspectWidth) { //window.CurSelectNode = null; } else if (BtNodeGraph.UpPointRect.Contains(curEvent.mousePosition)) { curEvent.Use(); if (!IsRoot) { if (IsHaveParent) { Parent.ChildNodeList.Remove(this); Parent.Data.children.Remove(Data); Owner.AddBrokenNode(this); Parent = null; } else { window.CurSelectNode = this; mIsLinkParent = true; } } } else if (BtNodeGraph.NodeRect.Contains(curEvent.mousePosition)) { curEvent.Use(); window.CurSelectNode = this; mCanDragMove = true; } else { window.CurSelectNode = null; } } else if (curEvent.type == EventType.MouseUp && curEvent.button == 0) { //松开鼠标 if (mIsDragging) { curEvent.Use(); mIsDragging = false; if (BtEditorWindow.IsAutoAlign) { SetNodePosition(this); } } if (mIsLinkParent) { mIsLinkParent = false; var parent = window.GetMouseTriggerDownPoint(curEvent.mousePosition); if (parent != null && parent != this && parent.ChildNodeList.Count < parent.Type.CanAddNodeCount) { parent.ChildNodeList.Add(this); parent.Data.AddChild(Data); Owner.RemoveBrokenNode(this); Parent = parent; } } mCanDragMove = false; } else if (curEvent.type == EventType.ContextClick) { if (BtNodeGraph.NodeRect.Contains(curEvent.mousePosition)) { //显示右键菜单 ShowMenu(); } } }
public Root(BtNode node) : base(node) { }
public Decorator(BtNode node) : base(node) { }
public void RemoveNode(BtNode node) { NodeDict.Remove(node.Guid); BrokenNodeDict.Remove(node.Guid); NodePosDict.Remove(node.Data.GetPosition().ToString()); }
public Task(BtNode node) : base(node) { }
public void RemoveBrokenNode(BtNode node) { BrokenNodeDict.Remove(node.Guid); }
protected BtNodeType(BtNode node) { BelongNode = node; }