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);
        }
Example #3
0
        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();
        }
Example #4
0
 public override void OnEnter()
 {
     base.OnEnter();
     lastRunningNode = null;
 }
Example #5
0
 public void DrawGraph(NodeBase rootNode, bool isEditable = false)
 {
     GUILayout.Space(10);
     DrawGraphRecusively(rootNode, isEditable);
 }