public NodeBase Analysis(BehaviorTreeData data, IConditionCheck iConditionCheck, Action <NodeAction> ActionNodeCallBack) { NodeBase rootNode = null; if (null == data) { Debug.LogError("数据无效"); return(rootNode); } if (data.rootNodeId < 0) { Debug.LogError("没有跟节点"); return(rootNode); } iConditionCheck.AddParameter(data.parameterList); Dictionary <int, NodeBase> compositeDic = new Dictionary <int, NodeBase>(); Dictionary <int, NodeBase> allNodeDic = new Dictionary <int, NodeBase>(); Dictionary <int, List <int> > childDic = new Dictionary <int, List <int> >(); for (int i = 0; i < data.nodeList.Count; ++i) { NodeValue nodeValue = data.nodeList[i]; NodeBase nodeBase = AnalysisNode(nodeValue, iConditionCheck); nodeBase.NodeId = nodeValue.id; if (!IsLeafNode(nodeValue.NodeType)) { compositeDic[nodeValue.id] = nodeBase; childDic[nodeValue.id] = nodeValue.childNodeList; if (data.rootNodeId == nodeValue.id) { rootNode = nodeBase; } } if (null == nodeBase) { Debug.LogError("AllNODE:" + nodeValue.id + " " + (null != nodeBase)); } if (nodeValue.NodeType == (int)NODE_TYPE.ACTION && null != ActionNodeCallBack) { ActionNodeCallBack((NodeAction)nodeBase); } allNodeDic[nodeValue.id] = nodeBase; } foreach (var kv in compositeDic) { int id = kv.Key; NodeComposite composite = (NodeComposite)(kv.Value); List <int> childList = childDic[id]; for (int i = 0; i < childList.Count; ++i) { int nodeId = childList[i]; NodeBase childNode = allNodeDic[nodeId]; if (null == childNode) { Debug.LogError("null node :" + nodeId); continue; } composite.AddNode(childNode); } } return(rootNode); }
private NodeBase AnalysisNode(NodeValue nodeValue, IConditionCheck iConditionCheck) { NodeBase node = null; if (nodeValue.NodeType == (int)NODE_TYPE.SELECT) // 选择节点 { return(GetSelect(nodeValue)); } if (nodeValue.NodeType == (int)NODE_TYPE.SEQUENCE) // 顺序节点 { return(GetSequence(nodeValue)); } if (nodeValue.NodeType == (int)NODE_TYPE.RANDOM) // 随机节点 { return(GetRandom(nodeValue)); } if (nodeValue.NodeType == (int)NODE_TYPE.PARALLEL) // 并行节点 { return(GetParallel(nodeValue)); } if (nodeValue.NodeType == (int)NODE_TYPE.DECORATOR_INVERTER) // 修饰节点_取反 { return(GetInverter(nodeValue)); } if (nodeValue.NodeType == (int)NODE_TYPE.DECORATOR_REPEAT) // 修饰节点_重复 { return(GetRepeat(nodeValue)); } if (nodeValue.NodeType == (int)NODE_TYPE.DECORATOR_RETURN_FAIL) // 修饰节点_返回Fail { return(GetReturenFail(nodeValue)); } if (nodeValue.NodeType == (int)NODE_TYPE.DECORATOR_RETURN_SUCCESS) // 修饰节点_返回Success { return(GetReturnSuccess(nodeValue)); } if (nodeValue.NodeType == (int)NODE_TYPE.DECORATOR_UNTIL_FAIL) // 修饰节点_直到Fail { return(GetUntilFail(nodeValue)); } if (nodeValue.NodeType == (int)NODE_TYPE.DECORATOR_UNTIL_SUCCESS) // 修饰节点_直到Success { return(GetUntilSuccess(nodeValue)); } if (nodeValue.NodeType == (int)NODE_TYPE.CONDITION) // 条件节点 { return(GetCondition(nodeValue, iConditionCheck)); } if (nodeValue.NodeType == (int)NODE_TYPE.ACTION) // 行为节点 { return(GetAction(nodeValue)); } return(node); }
void DrawGraphRecusively(NodeBase node, bool isEditable = false) { EditorGUILayout.BeginVertical(); { Rect parentRect; var children = node.GetAllChildren(); var fields = node.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); Dictionary <string, object> changedValues = new Dictionary <string, object>(); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); { Color defaultColor = GUI.color; GUILayout.BeginVertical(node.GetType().Name.Substring(4, node.GetType().Name.Length - 4), "window", GUILayout.Width(200)); switch (node.State) { case NodeState.Running: GUI.color = Color.yellow; break; case NodeState.Success: GUI.color = Color.green; break; case NodeState.Fail: GUI.color = Color.red; break; } if (node.parentNode != null && isEditable == true) { var parentNode = node.parentNode; var nodeIndex = parentNode.ChildIndexOf(node); GUILayout.BeginHorizontal(); if (GUILayout.Button("◀") && nodeIndex > 0) { parentNode.RemoveChild(node); parentNode.AddChild(node, nodeIndex - 1); } if (GUILayout.Button("▲") && parentNode.parentNode != null) { parentNode.RemoveChild(node); parentNode.parentNode.AddChild(node); } if (GUILayout.Button("▼") && nodeIndex > 0 && parentNode.GetChildrenCount() >= 2) { parentNode.RemoveChild(node); parentNode.GetChild(nodeIndex - 1).AddChild(node); } if (GUILayout.Button("▶") && nodeIndex < parentNode.GetChildrenCount() - 1) { parentNode.RemoveChild(node); parentNode.AddChild(node, nodeIndex + 1); } GUILayout.EndHorizontal(); } else { GUILayout.Box("", GUILayout.ExpandWidth(true)); } if (isEditable == true) { GUILayout.BeginHorizontal(); if (GUILayout.Button("Copy")) { m_CopiedAttributes.Clear(); for (int i = 0; i < fields.Length; i++) { object[] attributes = fields[i].GetCustomAttributes(typeof(NodeAttribute), true); if (attributes == null || attributes.Length == 0) { continue; } NodeAttribute nodeAttr = attributes[0] as NodeAttribute; if (nodeAttr == null) { continue; } if (nodeAttr.Option != NodeAttributeOptionType.Required) { continue; } m_CopiedAttributes.Add(nodeAttr.Name, fields[i].GetValue(node)); } } if (GUILayout.Button("Paste")) { for (int i = 0; i < fields.Length; i++) { object[] attributes = fields[i].GetCustomAttributes(typeof(NodeAttribute), true); if (attributes == null || attributes.Length == 0) { continue; } NodeAttribute nodeAttr = attributes[0] as NodeAttribute; if (nodeAttr == null) { continue; } if (m_CopiedAttributes.ContainsKey(nodeAttr.Name) == false) { continue; } fields[i].SetValue(node, m_CopiedAttributes[nodeAttr.Name]); } } if (GUILayout.Button("Delete") && node.parentNode != null) { var parentNode = node.parentNode; parentNode.RemoveChild(node); } GUILayout.EndHorizontal(); } else { GUILayout.Box("", GUILayout.ExpandWidth(true)); } if (node is NodeRoot) { GUILayout.Label("", GUILayout.Width(GRAPH_WINDOW_NAME_WIDTH + GRAPH_WINDOW_VALUE_WIDTH)); } else { EditorGUILayout.BeginHorizontal(); GUILayout.Label("Name", GUILayout.Width(GRAPH_WINDOW_NAME_WIDTH)); var changedName = EditorGUILayout.TextField(node.Name, GUILayout.Width(GRAPH_WINDOW_VALUE_WIDTH)); if (changedName != node.Name) { changedValues.Add("Name", changedName); } EditorGUILayout.EndHorizontal(); } EditorGUILayout.BeginHorizontal(); GUILayout.Label("State", GUILayout.Width(GRAPH_WINDOW_NAME_WIDTH)); GUILayout.Label(node.State.ToString(), GUILayout.Width(GRAPH_WINDOW_VALUE_WIDTH)); EditorGUILayout.EndHorizontal(); GUILayout.Space(10); for (int i = 0; i < fields.Length; i++) { object[] attributes = fields[i].GetCustomAttributes(typeof(NodeAttribute), true); if (attributes == null || attributes.Length == 0) { continue; } NodeAttribute nodeAttr = attributes[0] as NodeAttribute; if (nodeAttr == null) { continue; } if (nodeAttr.Name == "Name") { continue; } // if (nodeAttr.Option != NodeAttributeOptionType.Required) continue; EditorGUILayout.BeginHorizontal(); GUILayout.Label(nodeAttr.Name, GUILayout.Width(GRAPH_WINDOW_NAME_WIDTH)); object changedValue = null; if (fields[i].FieldType == typeof(string)) { changedValue = EditorGUILayout.TextField((string)fields[i].GetValue(node), GUILayout.Width(GRAPH_WINDOW_VALUE_WIDTH)); } else if (fields[i].FieldType == typeof(int)) { changedValue = EditorGUILayout.IntField((int)fields[i].GetValue(node), GUILayout.Width(GRAPH_WINDOW_VALUE_WIDTH)); } else if (fields[i].FieldType == typeof(long)) { changedValue = EditorGUILayout.LongField((long)fields[i].GetValue(node), GUILayout.Width(GRAPH_WINDOW_VALUE_WIDTH)); } else if (fields[i].FieldType == typeof(float)) { changedValue = EditorGUILayout.FloatField((float)fields[i].GetValue(node), GUILayout.Width(GRAPH_WINDOW_VALUE_WIDTH)); } else if (fields[i].FieldType == typeof(double)) { changedValue = EditorGUILayout.DoubleField((double)fields[i].GetValue(node), GUILayout.Width(GRAPH_WINDOW_VALUE_WIDTH)); } else if (fields[i].FieldType == typeof(bool)) { changedValue = EditorGUILayout.Toggle((bool)fields[i].GetValue(node), GUILayout.Width(GRAPH_WINDOW_VALUE_WIDTH)); } else if (fields[i].FieldType.IsEnum) { changedValue = EditorGUILayout.EnumPopup((Enum)fields[i].GetValue(node), GUILayout.Width(GRAPH_WINDOW_VALUE_WIDTH)); } else { GUILayout.Label(fields[i].FieldType.Name, GUILayout.Width(GRAPH_WINDOW_VALUE_WIDTH)); } EditorGUILayout.EndHorizontal(); if (changedValue != null) { if (changedValue is IComparable) { if (((IComparable)fields[i].GetValue(node)).CompareTo(changedValue) != 0) { changedValues.Add(nodeAttr.Name, changedValue); } } else { if (fields[i].GetValue(node) != changedValue) { changedValues.Add(nodeAttr.Name, changedValue); } } } } if (isEditable == true) { GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); var addSelectedIndex = EditorGUILayout.Popup(0, ADDABLE_NODE_TYPES, GUILayout.Width(GRAPH_WINDOW_VALUE_WIDTH)); if (addSelectedIndex > 0) { Type nodeType = Util.GetNodeType(ADDABLE_NODE_TYPES[addSelectedIndex]); if (nodeType != null) { NodeBase newNode = Activator.CreateInstance(nodeType) as NodeBase; node.AddChild(newNode); } } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } else { GUILayout.Box("", GUILayout.ExpandWidth(true)); } GUILayout.EndVertical(); parentRect = GUILayoutUtility.GetLastRect(); GUI.color = defaultColor; } GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); if (isEditable == true && changedValues.Count > 0) { for (int i = 0; i < fields.Length; i++) { object[] attributes = fields[i].GetCustomAttributes(typeof(NodeAttribute), true); if (attributes == null || attributes.Length == 0) { continue; } NodeAttribute nodeAttr = attributes[0] as NodeAttribute; if (nodeAttr == null) { continue; } if (changedValues.ContainsKey(nodeAttr.Name) == false) { continue; } fields[i].SetValue(node, changedValues[nodeAttr.Name]); } } if (children.Length > 0) { GUILayout.Space(GRAPH_SPACE_Y - 10); GUILayout.Box("", GUILayout.ExpandWidth(true), GUILayout.Height(10)); EditorGUILayout.BeginHorizontal(); GUILayout.Box("", GUILayout.Width(10), GUILayout.ExpandHeight(true)); GUILayout.Space(GRAPH_SPACE_X - 10); for (int i = 0; i < children.Length; i++) { if (i > 0) { GUILayout.Space(GRAPH_SPACE_X); } DrawGraphRecusively(children[i], isEditable); Rect childRect = GUILayoutUtility.GetLastRect(); Vector3 startPos = new Vector3( parentRect.center.x, parentRect.center.y + parentRect.height * 0.5f, 0); Vector3 endPos = new Vector3( childRect.center.x, childRect.center.y - childRect.height * 0.5f, 0); if (EditorGUIUtility.isProSkin == false) //outline { Handles.DrawBezier(startPos, endPos, new Vector3(startPos.x, endPos.y, 0), new Vector3(endPos.x, startPos.y, 0), Color.black, null, 4f); } Handles.DrawBezier(startPos, endPos, new Vector3(startPos.x, endPos.y, 0), new Vector3(endPos.x, startPos.y, 0), children[i].State == NodeState.Running ? Color.yellow : Color.white, null, 2f); } GUILayout.Space(GRAPH_SPACE_X - 10); GUILayout.Box("", GUILayout.Width(10), GUILayout.ExpandHeight(true)); EditorGUILayout.EndHorizontal(); } GUILayout.FlexibleSpace(); } EditorGUILayout.EndVertical(); }
public override void OnEnter() { base.OnEnter(); lastRunningNode = null; }
public void DrawGraph(NodeBase rootNode, bool isEditable = false) { GUILayout.Space(10); DrawGraphRecusively(rootNode, isEditable); }