void NodeRemoveRequested(BehaviorNodeControl node)
        {
            if (m_linkFrom == node)
            {
                m_linkFrom      = null;
                m_linkLine.From = Vector2.zero;
                m_linkLine.To   = Vector2.zero;
            }

            foreach (BehaviorNodeControl c in m_nodes)
            {
                if (c != node)
                {
                    for (int i = c.m_outputs.Count - 1; i >= 0; i--)
                    {
                        if (c.m_outputs[i] == node)
                        {
                            c.ClearOutput(i);
                        }
                    }
                }
            }

            node.Remove();
            node.DragMoved       -= NodeDragMoved;
            node.OutputClicked   -= NodeOutputClicked;
            node.RemoveRequested -= NodeRemoveRequested;

            RemoveChild(node);

            m_nodes.Remove(node);
        }
        protected override void OnMouseDown(Event e)
        {
            switch (e.button)
            {
            case 0:
                if (m_linkFrom != null)
                {
                    BehaviorNodeControl node = IsPointOnNode(e.mousePosition);

                    if (node != null)
                    {
                        m_linkFrom.SetOutput(node, m_linkFromIndex);
                    }

                    m_linkFrom      = null;
                    m_linkLine.From = Vector2.zero;
                    m_linkLine.To   = Vector2.zero;

                    e.Use();
                }
                break;

            case 1:
                if (m_linkFrom != null)
                {
                    m_linkFrom      = null;
                    m_linkLine.From = Vector2.zero;
                    m_linkLine.To   = Vector2.zero;

                    e.Use();
                }
                break;
            }
        }
        private void NodeDragMoved(IDraggable sender, DragEventArgs args, Event nativeEvent)
        {
            if (sender is BehaviorNodeControl)
            {
                BehaviorNodeControl node = sender as BehaviorNodeControl;

                switch (nativeEvent.button)
                {
                case 0:
                {
                    Vector2 newPos = node.Position + args.delta;

                    if (newPos.x >= 0.0f && newPos.y >= 0.0f)
                    {
                        node.SetPosition(newPos);
                    }
                }
                break;

                case 2:
                {
                    Vector2 newPos = node.Position + args.delta;

                    if (newPos.x >= 0.0f && newPos.y >= 0.0f)
                    {
                        DragHierarchy(node, args.delta);
                    }
                }
                break;
                }
            }
        }
        private void SaveXML(string path, BehaviorNodeControl root)
        {
            BehaviorTreeXMLSerializer serializer = new BehaviorTreeXMLSerializer();
            string xml = serializer.Serialize(m_tools.TreeIdField.Value, root);

            File.WriteAllText(path, xml);
            AssetDatabase.Refresh();
        }
        private string SerializeAttribute(BehaviorNodeControl node, EditorCachedNodeField field)
        {
            if (node.m_fieldControls.ContainsKey(field.name))
            {
                Control c = node.m_fieldControls[field.name];

                if (field.type == typeof(int))
                {
                    return(string.Format("{0}=\"{1}\"", field.systemName, (c as IntField).Value));
                }
                else if (field.type == typeof(float))
                {
                    return(string.Format("{0}=\"{1}\"", field.systemName, (c as FloatField).Value));
                }
                else if (field.type == typeof(Vector2))
                {
                    return(string.Format("{0}=\"{1},{2}\"", field.systemName, (c as Vector2Field).Value.x, (c as Vector2Field).Value.y));
                }
                else if (field.type == typeof(Vector3))
                {
                    return(string.Format("{0}=\"{1},{2},{3}\"", field.systemName, (c as Vector3Field).Value.x, (c as Vector3Field).Value.y, (c as Vector3Field).Value.z));
                }
                else if (field.type == typeof(Vector4))
                {
                    return(string.Format("{0}=\"{1},{2},{3}\"", field.systemName, (c as Vector4Field).Value.x, (c as Vector4Field).Value.y, (c as Vector4Field).Value.z, (c as Vector4Field).Value.w));
                }
                else if (field.type == typeof(string))
                {
                    return(string.Format("{0}=\"{1}\"", field.systemName, (c as TextField).Value));
                }
                else if (field.type == typeof(Rect))
                {
                    return(string.Format("{0}=\"{1},{2},{3},{4}\"", field.systemName, (c as RectField).Value.xMin, (c as RectField).Value.yMin, (c as RectField).Value.width, (c as RectField).Value.height));
                }
                else if (field.type == typeof(Color))
                {
                    return(string.Format("{0}=\"{1},{2},{3}\"", field.systemName, (c as ColorField).Value.r, (c as ColorField).Value.g, (c as ColorField).Value.b, (c as ColorField).Value.a));
                }
                else if (field.type == typeof(Bounds))
                {
                    return(string.Format("{0}=\"{1},{2},{3},{4},{5},{6}\"", field.systemName, (c as BoundsField).Value.center.x, (c as BoundsField).Value.center.y, (c as BoundsField).Value.center.z, (c as BoundsField).Value.extents.x, (c as BoundsField).Value.extents.y, (c as BoundsField).Value.extents.z));
                }
                else if (field.type.IsEnum)
                {
                    return(string.Format("{0}=\"{1}\"", field.systemName, (c as EnumDropdown).Value));
                }
                else if (field.type == typeof(bool))
                {
                    return(string.Format("{0}=\"{1}\"", field.systemName, (c as Toggle).Value));
                }
            }

            return("");
        }
        private string SerializeAttribute( BehaviorNodeControl node, EditorCachedNodeField field )
        {
            if ( node.m_fieldControls.ContainsKey( field.name ) )
            {
                Control c = node.m_fieldControls[ field.name ];

                if ( field.type == typeof( int ) )
                {
                    return string.Format( "{0}=\"{1}\"", field.systemName, ( c as IntField ).Value );                    
                }
                else if ( field.type == typeof( float ) )
                {
                    return string.Format( "{0}=\"{1}\"", field.systemName, ( c as FloatField ).Value );                    
                }
                else if ( field.type == typeof( Vector2 ) )
                {
                    return string.Format( "{0}=\"{1},{2}\"", field.systemName, ( c as Vector2Field ).Value.x, ( c as Vector2Field ).Value.y );                      
                }
                else if ( field.type == typeof( Vector3 ) )
                {
                    return string.Format( "{0}=\"{1},{2},{3}\"", field.systemName, ( c as Vector3Field ).Value.x, ( c as Vector3Field ).Value.y, ( c as Vector3Field ).Value.z );                                          
                }
                else if ( field.type == typeof( Vector4 ) )
                {
                    return string.Format( "{0}=\"{1},{2},{3}\"", field.systemName, ( c as Vector4Field ).Value.x, ( c as Vector4Field ).Value.y, ( c as Vector4Field ).Value.z, ( c as Vector4Field ).Value.w );                                          
                }
                else if ( field.type == typeof( string ) )
                {
                    return string.Format( "{0}=\"{1}\"", field.systemName, ( c as TextField ).Value );                    
                }
                else if ( field.type == typeof( Rect ) )
                {
                    return string.Format( "{0}=\"{1},{2},{3},{4}\"", field.systemName, ( c as RectField ).Value.xMin, ( c as RectField ).Value.yMin, ( c as RectField ).Value.width, ( c as RectField ).Value.height );                    
                }
                else if ( field.type == typeof( Color ) )
                {
                    return string.Format( "{0}=\"{1},{2},{3}\"", field.systemName, ( c as ColorField ).Value.r, ( c as ColorField ).Value.g, ( c as ColorField ).Value.b, ( c as ColorField ).Value.a );
                }
                else if ( field.type == typeof( Bounds ) )
                {
                    return string.Format( "{0}=\"{1},{2},{3},{4},{5},{6}\"", field.systemName, ( c as BoundsField ).Value.center.x, ( c as BoundsField ).Value.center.y, ( c as BoundsField ).Value.center.z, ( c as BoundsField ).Value.extents.x, ( c as BoundsField ).Value.extents.y, ( c as BoundsField ).Value.extents.z );                    
                }
                else if ( field.type.IsEnum )
                {
                    return string.Format( "{0}=\"{1}\"", field.systemName, ( c as EnumDropdown ).Value );                    
                }
                else if ( field.type == typeof( bool ) )
                {
                    return string.Format( "{0}=\"{1}\"", field.systemName, ( c as Toggle ).Value );                    
                }
            }

            return "";
        }
        private void IndexNode( BehaviorNodeControl node )
        {
            if ( !m_indexTable.ContainsKey( node ) )
            {
                m_indexTable.Add( node, string.Format( "n{0}", m_indexTable.Keys.Count + 1 ) );
            }

            foreach ( BehaviorNodeControl o in node.m_outputs )
            {
                IndexNode( o );
            }
        }
Beispiel #8
0
        private void IndexNode(BehaviorNodeControl node)
        {
            if (!m_indexTable.ContainsKey(node))
            {
                m_indexTable.Add(node, string.Format("n{0}", m_indexTable.Keys.Count + 1));
            }

            foreach (BehaviorNodeControl o in node.m_outputs)
            {
                IndexNode(o);
            }
        }
        public void AddNodeGroup( BehaviorNodeControl[] nodes )
        {
            foreach( BehaviorNodeControl node in nodes )
            {
                node.DragMoved += NodeDragMoved;
                node.OutputClicked += NodeOutputClicked;
                node.RemoveRequested += NodeRemoveRequested;

                AddChild( node );
                m_nodes.Add( node );
            }
        }
        private void DragHierarchy(BehaviorNodeControl c, Vector2 delta)
        {
            c.SetPosition(c.Position + delta);

            foreach (BehaviorNodeControl o in c.m_outputs)
            {
                if (o != null)
                {
                    DragHierarchy(o, delta);
                }
            }
        }
        public string Serialize( string id, BehaviorNodeControl root )
        {
            m_indexTable = new BehaviorTreeNodeIndexer( root ).IndexTable;

            string nodes = "";
            foreach( BehaviorNodeControl node in m_indexTable.Keys )
            {
                nodes = string.Format( "{0}\n{1}", nodes, SerializeNode( node ) );
            }
            nodes = string.Format( "{0}\n", nodes );

            return string.Format( TEMPLATE, id, nodes );
        }
        public string Serialize(string id, BehaviorNodeControl root)
        {
            m_indexTable = new BehaviorTreeNodeIndexer(root).IndexTable;

            string nodes = "";

            foreach (BehaviorNodeControl node in m_indexTable.Keys)
            {
                nodes = string.Format("{0}\n{1}", nodes, SerializeNode(node));
            }
            nodes = string.Format("{0}\n", nodes);

            return(string.Format(TEMPLATE, id, nodes));
        }
        void SaveButton_Clicked(IClickable sender, ClickEventArgs args, Event nativeEvent)
        {
            BehaviorNodeControl root = m_editor.GetRootControl();

            if (root != null)
            {
                string path = EditorUtility.SaveFilePanelInProject("Save Behavior Layout", string.Format("Layout{0}", m_tools.TreeIdField.Value), "xml", "");

                if (!string.IsNullOrEmpty(path))
                {
                    SaveXML(path, root);
                }
            }
        }
        private void AddNode(object cachedNode)
        {
            if (cachedNode is EditorCachedNode)
            {
                BehaviorNodeControl node = new BehaviorNodeControl(( EditorCachedNode )cachedNode);
                node.Position = m_mousePosition;

                node.DragMoved       += NodeDragMoved;
                node.OutputClicked   += NodeOutputClicked;
                node.RemoveRequested += NodeRemoveRequested;

                AddChild(node);
                m_nodes.Add(node);
            }
        }
        private string GenerateChildLinks(BehaviorNodeControl node)
        {
            string s = "";

            if (node.m_outputs.Count > 0)
            {
                s = "\n";
            }

            foreach (BehaviorNodeControl o in node.m_outputs)
            {
                s = string.Format("{0}\t\t{1}.Children.Add({2});\n", s, m_indexTable[node], m_indexTable[o]);
            }

            return(s);
        }
        void GenerateButton_Clicked(IClickable sender, ClickEventArgs args, Event nativeEvent)
        {
            BehaviorNodeControl root = m_editor.GetRootControl();

            if (root != null)
            {
                SaveXML(Application.persistentDataPath + "/" + TEMP_FILENAME, root);
                EditorPrefs.SetBool(TEMP_FILE_KEY, true);

                string safeHandle = m_tools.TreeIdField.Value.Replace(" ", "");

                BehaviorTreeGenerator generator = new BehaviorTreeGenerator();
                string output = generator.Generate(m_tools.TreeIdField.Value, safeHandle, root);

                SaveSourceFile(safeHandle, output);
            }
        }
        private bool CheckCircularReference(BehaviorNodeControl target, BehaviorNodeControl source)
        {
            if (source == target)
            {
                return(true);
            }

            foreach (BehaviorNodeControl child in source.m_outputs)
            {
                if (CheckCircularReference(target, child))
                {
                    return(true);
                }
            }

            return(false);
        }
        private string SerializeNode(BehaviorNodeControl node)
        {
            EditorCachedNode data = node.GetData();

            string id       = m_indexTable[node];;
            string position = string.Format("{0},{1}", node.Position.x, node.Position.y);
            string type     = data.type.ToString();
            string attribs  = "";
            string children = "";

            for (int i = 0; i < data.fields.Length; i++)
            {
                if (i > 0)
                {
                    attribs += " ";
                }

                attribs += SerializeAttribute(node, data.fields[i]);
            }

            if (node.m_outputs.Count > 0)
            {
                children = "outputs=\"";
            }

            for (int i = 0; i < node.m_outputs.Count; i++)
            {
                if (i > 0)
                {
                    children += ",";
                }

                children += m_indexTable[node.m_outputs[i]];
            }

            if (node.m_outputs.Count > 0)
            {
                children += "\"";
            }

            return(string.Format(NODE_TEMPLATE, id, position, type, attribs, children));;
        }
        public void SetOutput(BehaviorNodeControl target, int index)
        {
            // Not self
            if (target == this)
            {
                return;
            }

            // Make sure connection does not already exist
            foreach (BehaviorNodeControl o in m_outputs)
            {
                if (o == target)
                {
                    return;
                }
            }

            // Make sure there are no circular references
            foreach (BehaviorNodeControl o in target.m_outputs)
            {
                if (CheckCircularReference(this, o))
                {
                    return;
                }
            }

            if (index < m_outputs.Count)
            {
                // Replace
                m_outputs[index] = target;
            }
            else
            {
                // New connection

                m_outputs.Add(target);
                BezierCurve line = (BezierCurve)m_canvas.AddShape(new BezierCurve(GetOutputConnectorPosition(index), target.GetInputConnectorPosition(), Color.red, 1.0f, BezierCurve.TangentMode.AutoY, Vector2.zero, Vector2.zero));
                m_outputLines.Add(line);

                UpdateOutputs();
            }
        }
        private string SerializeNode( BehaviorNodeControl node )
        {
            EditorCachedNode data = node.GetData();

            string id           = m_indexTable[ node ]; ;
            string position     = string.Format( "{0},{1}", node.Position.x, node.Position.y );
            string type         = data.type.ToString();
            string attribs      = "";
            string children     = "";

            for ( int i = 0; i < data.fields.Length; i++ )
            {
                if ( i > 0 )
                {
                    attribs += " ";
                }

                attribs += SerializeAttribute( node, data.fields[ i ] );                
            }

            if ( node.m_outputs.Count > 0 )
            {
                children = "outputs=\"";
            }

            for ( int i = 0; i < node.m_outputs.Count; i++ )
            {
                if ( i > 0 )
                {
                    children += ",";
                }

                children += m_indexTable[ node.m_outputs[ i ] ];
            }

            if ( node.m_outputs.Count > 0 )
            {
                children += "\"";
            }

            return string.Format( NODE_TEMPLATE, id, position, type, attribs, children ); ;
        }
        public string Generate( string id, string safeHandle, BehaviorNodeControl root )
        {
            m_indexTable = new BehaviorTreeNodeIndexer( root ).IndexTable;            

            string code = "";

            foreach( BehaviorNodeControl node in m_indexTable.Keys )
            {
                code = string.Format( "{0}\n{1}\n", code, GenerateNodeCode( node ) );
            }

            foreach ( BehaviorNodeControl node in m_indexTable.Keys )
            {
                code = string.Format( "{0}{1}", code, GenerateChildLinks( node ) );
            }

            return string.Format(
                TEMPLATE, System.DateTime.Now, safeHandle, id, code
            );
        }
        public string Generate(string id, string safeHandle, BehaviorNodeControl root)
        {
            m_indexTable = new BehaviorTreeNodeIndexer(root).IndexTable;

            string code = "";

            foreach (BehaviorNodeControl node in m_indexTable.Keys)
            {
                code = string.Format("{0}\n{1}\n", code, GenerateNodeCode(node));
            }

            foreach (BehaviorNodeControl node in m_indexTable.Keys)
            {
                code = string.Format("{0}{1}", code, GenerateChildLinks(node));
            }

            return(string.Format(
                       TEMPLATE, System.DateTime.Now, safeHandle, id, code
                       ));
        }
        private BehaviorNodeControl DeserializeNode(XmlNode xml, EditorNodeTypeCache typeCache, out string nodeId, out List <string> childIds)
        {
            childIds = new List <string>();

            nodeId = xml.Attributes["id"].InnerText;
            string type = xml.Attributes["type"].InnerText;

            string[] posStr   = xml.Attributes["position"].InnerText.Split(',');
            Vector2  position = new Vector2(float.Parse(posStr[0]), float.Parse(posStr[1]));

            if (xml.Attributes["outputs"] != null)
            {
                childIds.AddRange(xml.Attributes["outputs"].InnerText.Split(','));
            }

            bool             found = false;
            EditorCachedNode data  = default(EditorCachedNode);

            foreach (EditorCachedNode cachedType in typeCache.Cache)
            {
                if (cachedType.type.ToString() == type)
                {
                    found = true;
                    data  = cachedType;
                    break;
                }
            }

            if (!found)
            {
                return(null);
            }

            BehaviorNodeControl control = new BehaviorNodeControl(data);

            control.SetPosition(position);
            DeserializeFields(xml, data, control);

            return(control);
        }
        void NodeOutputClicked(BehaviorNodeControl node, int index, MouseButton mouseButton)
        {
            switch (mouseButton)
            {
            case MouseButton.Left:
                m_linkFrom      = node;
                m_linkFromIndex = index;
                break;

            case MouseButton.Right:
                if (m_linkFrom == null)
                {
                    node.ClearOutput(index);
                }
                else
                {
                    m_linkFrom      = null;
                    m_linkLine.From = Vector2.zero;
                    m_linkLine.To   = Vector2.zero;
                }
                break;
            }
        }
        void NodeOutputClicked( BehaviorNodeControl node, int index, MouseButton mouseButton )
        {
            switch ( mouseButton )
            {
                case MouseButton.Left:
                    m_linkFrom = node;
                    m_linkFromIndex = index;
                break;

                case MouseButton.Right:
                    if ( m_linkFrom == null )
                    {
                        node.ClearOutput( index );
                    }
                    else
                    {
                        m_linkFrom = null;
                        m_linkLine.From = Vector2.zero;
                        m_linkLine.To = Vector2.zero;
                    }
                break;
            }
        }
        void NodeRemoveRequested( BehaviorNodeControl node )
        {
            if ( m_linkFrom == node )
            {
                m_linkFrom = null;
                m_linkLine.From = Vector2.zero;
                m_linkLine.To = Vector2.zero;
            }

            foreach( BehaviorNodeControl c in m_nodes )
            {
                if ( c != node )
                {
                    for ( int i =  c.m_outputs.Count - 1; i >= 0; i-- )
                    {
                        if ( c.m_outputs[ i ] == node )
                        {
                            c.ClearOutput( i );
                        }
                    }
                }
            }

            node.Remove();
            node.DragMoved       -= NodeDragMoved;
            node.OutputClicked   -= NodeOutputClicked;
            node.RemoveRequested -= NodeRemoveRequested;            

            RemoveChild( node );

            m_nodes.Remove( node );
        }
        private void AddNode( object cachedNode )
        {
            if ( cachedNode is EditorCachedNode )
            {
                BehaviorNodeControl node = new BehaviorNodeControl( ( EditorCachedNode )cachedNode );
                node.Position = m_mousePosition;

                node.DragMoved += NodeDragMoved;
                node.OutputClicked += NodeOutputClicked;
                node.RemoveRequested += NodeRemoveRequested;

                AddChild( node );
                m_nodes.Add( node );
            }
        }
        public bool Deserialize( string path, EditorNodeTypeCache typeCache, out string id, out BehaviorNodeControl[] controls )
        {
            id = "";
            controls = new BehaviorNodeControl[ 0 ];

            m_childMapping = new Dictionary<BehaviorNodeControl, List<string>>();

            try
            {
                m_indexTable = new Dictionary<BehaviorNodeControl, string>();

                XmlDocument xml = new XmlDocument();
                xml.Load( path );

                XmlNode xmlRoot = xml.SelectSingleNode( "BehaviorTreeLayout" );
                id = xmlRoot.Attributes[ "id" ].InnerText;

                List< BehaviorNodeControl > deserialized = new List<BehaviorNodeControl>();
                XmlNodeList xmlNodes = xmlRoot.SelectNodes( "Node" );
                foreach( XmlNode xmlNode in xmlNodes )
                {
                    string nodeId;
                    List< string > children;
                    BehaviorNodeControl c = DeserializeNode( xmlNode, typeCache, out nodeId, out children );

                    if ( c != null )
                    {
                        m_indexTable.Add( c, nodeId );
                        m_childMapping.Add( c, children );
                        deserialized.Add( c );
                    }
                    else
                    {
                        Debug.LogWarning( "Invalid node encountered, not all nodes have been deserialized" );
                    }
                }

                // Map outputs
                foreach( BehaviorNodeControl c in deserialized )
                {
                    if ( m_childMapping.ContainsKey( c ) )
                    {
                        int i = 0;
                        foreach( string cid in m_childMapping[ c ] )
                        {
                            foreach( KeyValuePair< BehaviorNodeControl, string > kvp in m_indexTable )
                            {
                                if ( kvp.Value == cid )
                                {
                                    c.SetOutput( kvp.Key, i );
                                    i++;
                                    break;
                                }
                            }
                        }
                    }
                }

                controls = deserialized.ToArray();

                return true;
            }
            catch( System.Exception e )
            {
                Debug.LogError( string.Format( "Could not load layout at `{0}` - {1}", path, e.Message ) );
            }

            return false;
        }
        private string GenerateNodeCode( BehaviorNodeControl node )
        {
            EditorCachedNode data = node.GetData();

            string s = "\n";
            s = string.Format( "\t\t{0} {1} = new {0}( t );", data.type, m_indexTable[ node ] );

            foreach( EditorCachedNodeField field in data.fields )
            {
                if ( node.m_fieldControls.ContainsKey( field.name ) )
                {
                    Control c = node.m_fieldControls[ field.name ];

                    if ( field.type == typeof( int ) )
                    {                        
                        s += string.Format( "\n\t\t{0}.{1} = {2};", m_indexTable[ node ], field.systemName, ( c as IntField ).Value );
                    }
                    else if ( field.type == typeof( float ) )
                    {
                        s += string.Format( "\n\t\t{0}.{1} = {2}f;", m_indexTable[ node ], field.systemName, ( c as FloatField ).Value );
                    }
                    else if ( field.type == typeof( Vector2 ) )
                    {
                        s += string.Format( "\n\t\t{0}.{1} = new Vector2({2}f,{3}f);", m_indexTable[ node ], field.systemName, ( c as Vector2Field ).Value.x, ( c as Vector2Field ).Value.y );
                    }
                    else if ( field.type == typeof( Vector3 ) )
                    {
                        s += string.Format( "\n\t\t{0}.{1} = new Vector3({2}f,{3}f,{4}f);", m_indexTable[ node ], field.systemName, ( c as Vector3Field ).Value.x, ( c as Vector3Field ).Value.y, ( c as Vector3Field ).Value.z );
                    }
                    else if ( field.type == typeof( Vector4 ) )
                    {
                        s += string.Format( "\n\t\t{0}.{1} = new Vector4({2}f,{3}f,{4}f,{5}f);", m_indexTable[ node ], field.systemName, ( c as Vector4Field ).Value.x, ( c as Vector4Field ).Value.y, ( c as Vector4Field ).Value.z, ( c as Vector4Field ).Value.w );
                    }
                    else if ( field.type == typeof( string ) )
                    {
                        s += string.Format( "\n\t\t{0}.{1} = \"{2}\";", m_indexTable[ node ], field.systemName, ( c as TextField ).Value );
                    }
                    else if ( field.type == typeof( Rect ) )
                    {
                        s += string.Format( "\n\t\t{0}.{1} = new Rect({2}f,{3}f,{4}f,{5}f);", m_indexTable[ node ], field.systemName, ( c as RectField ).Value.xMin, ( c as RectField ).Value.yMin, ( c as RectField ).Value.width, ( c as RectField ).Value.height );                        
                    }
                    else if ( field.type == typeof( Color ) )
                    {
                        s += string.Format( "\n\t\t{0}.{1} = new Color({2},{3},{4},{5});", m_indexTable[ node ], field.systemName, ( c as ColorField ).Value.r, ( c as ColorField ).Value.g, ( c as ColorField ).Value.b, ( c as ColorField ).Value.a );
                    }
                    else if ( field.type == typeof( Bounds ) )
                    {
                        s += string.Format( "\n\t\t{0}.{1} = new Bounds( new Vector3({2}f,{3}f,{4}f),new Vector3({5}f,{6}f,{7}f));", m_indexTable[ node ], field.systemName, ( c as BoundsField ).Value.center.x, ( c as BoundsField ).Value.center.y, ( c as BoundsField ).Value.center.z, ( c as BoundsField ).Value.extents.x, ( c as BoundsField ).Value.extents.y, ( c as BoundsField ).Value.extents.z );
                    }
                    else if ( field.type.IsEnum )
                    {
                        s += string.Format( "\n\t\t{0}.{1} = {2}.{3};", m_indexTable[ node ], field.systemName, field.type.ToString().Replace("+","."), ( c as EnumDropdown ).Value );
                    }
                    else if ( field.type == typeof( bool ) )
                    {
                        s += string.Format( "\n\t\t{0}.{1} = {2};", m_indexTable[ node ], field.systemName, ( c as Toggle ).Value.ToString().ToLowerInvariant() );
                    }
                }
            }

            return s;
        }
        public bool Deserialize(string path, EditorNodeTypeCache typeCache, out string id, out BehaviorNodeControl[] controls)
        {
            id       = "";
            controls = new BehaviorNodeControl[0];

            m_childMapping = new Dictionary <BehaviorNodeControl, List <string> >();

            try
            {
                m_indexTable = new Dictionary <BehaviorNodeControl, string>();

                XmlDocument xml = new XmlDocument();
                xml.Load(path);

                XmlNode xmlRoot = xml.SelectSingleNode("BehaviorTreeLayout");
                id = xmlRoot.Attributes["id"].InnerText;

                List <BehaviorNodeControl> deserialized = new List <BehaviorNodeControl>();
                XmlNodeList xmlNodes = xmlRoot.SelectNodes("Node");
                foreach (XmlNode xmlNode in xmlNodes)
                {
                    string              nodeId;
                    List <string>       children;
                    BehaviorNodeControl c = DeserializeNode(xmlNode, typeCache, out nodeId, out children);

                    if (c != null)
                    {
                        m_indexTable.Add(c, nodeId);
                        m_childMapping.Add(c, children);
                        deserialized.Add(c);
                    }
                    else
                    {
                        Debug.LogWarning("Invalid node encountered, not all nodes have been deserialized");
                    }
                }

                // Map outputs
                foreach (BehaviorNodeControl c in deserialized)
                {
                    if (m_childMapping.ContainsKey(c))
                    {
                        int i = 0;
                        foreach (string cid in m_childMapping[c])
                        {
                            foreach (KeyValuePair <BehaviorNodeControl, string> kvp in m_indexTable)
                            {
                                if (kvp.Value == cid)
                                {
                                    c.SetOutput(kvp.Key, i);
                                    i++;
                                    break;
                                }
                            }
                        }
                    }
                }

                controls = deserialized.ToArray();

                return(true);
            }
            catch (System.Exception e)
            {
                Debug.LogError(string.Format("Could not load layout at `{0}` - {1}", path, e.Message));
            }

            return(false);
        }
        private void DeserializeFields(XmlNode xml, EditorCachedNode data, BehaviorNodeControl control)
        {
            foreach (KeyValuePair <string, Control> kvp in control.m_fieldControls)
            {
                string  fieldName  = kvp.Key;
                string  systemName = "";
                Control c          = kvp.Value;

                bool found = false;
                EditorCachedNodeField field = default(EditorCachedNodeField);

                foreach (EditorCachedNodeField f in data.fields)
                {
                    if (f.name == fieldName)
                    {
                        found      = true;
                        field      = f;
                        systemName = f.systemName;
                        break;
                    }
                }

                if (!found)
                {
                    continue;
                }

                if (xml.Attributes[systemName] == null)
                {
                    continue;
                }

                string sval = xml.Attributes[systemName].InnerText;

                if (field.type == typeof(int))
                {
                    (c as IntField).Value = int.Parse(sval);
                }
                else if (field.type == typeof(float))
                {
                    (c as FloatField).Value = float.Parse(sval);
                }
                else if (field.type == typeof(Vector2))
                {
                    string[] split = sval.Split(',');
                    (c as Vector2Field).Value = new Vector2(float.Parse(split[0]), float.Parse(split[1]));
                }
                else if (field.type == typeof(Vector3))
                {
                    string[] split = sval.Split(',');
                    (c as Vector3Field).Value = new Vector3(float.Parse(split[0]), float.Parse(split[1]), float.Parse(split[2]));
                }
                else if (field.type == typeof(Vector4))
                {
                    string[] split = sval.Split(',');
                    (c as Vector4Field).Value = new Vector4(float.Parse(split[0]), float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3]));
                }
                else if (field.type == typeof(string))
                {
                    (c as TextField).Value = sval;
                }
                else if (field.type == typeof(Rect))
                {
                    string[] split = sval.Split(',');
                    (c as RectField).Value = new Rect(float.Parse(split[0]), float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3]));
                }
                else if (field.type == typeof(Color))
                {
                    string[] split = sval.Split(',');
                    (c as ColorField).Value = new Color(float.Parse(split[0]), float.Parse(split[1]), float.Parse(split[2]));
                }
                else if (field.type == typeof(Bounds))
                {
                    string[] split = sval.Split(',');
                    (c as BoundsField).Value = new Bounds(new Vector3(float.Parse(split[0]), float.Parse(split[1]), float.Parse(split[2])), new Vector3(float.Parse(split[3]), float.Parse(split[4]), float.Parse(split[5])));
                }
                else if (field.type.IsEnum)
                {
                    System.Enum e = (System.Enum)System.Enum.Parse(field.type, sval);
                    (c as EnumDropdown).Value = e;
                }
                else if (field.type == typeof(bool))
                {
                    (c as Toggle).Value = bool.Parse(sval);
                }
            }
        }
        private void DeserializeFields( XmlNode xml, EditorCachedNode data, BehaviorNodeControl control )
        {
            foreach( KeyValuePair< string, Control > kvp in control.m_fieldControls )
            {
                string fieldName  = kvp.Key;
                string systemName = "";
                Control c         = kvp.Value;

                bool found = false;
                EditorCachedNodeField field = default(EditorCachedNodeField);

                foreach( EditorCachedNodeField f in data.fields )
                {
                    if ( f.name == fieldName )
                    {
                        found = true;
                        field = f;
                        systemName = f.systemName;
                        break;
                    }
                }

                if ( !found )
                {
                    continue;
                }

                if ( xml.Attributes[ systemName ] == null )
                {
                    continue;
                }

                string sval = xml.Attributes[ systemName ].InnerText;

                if ( field.type == typeof( int ) )
                {
                    ( c as IntField ).Value = int.Parse( sval );
                }
                else if ( field.type == typeof( float ) )
                {
                    ( c as FloatField ).Value = float.Parse( sval );
                }
                else if ( field.type == typeof( Vector2 ) )
                {
                    string[] split = sval.Split( ',' );
                    ( c as Vector2Field ).Value = new Vector2( float.Parse( split[ 0 ] ), float.Parse( split[ 1 ] ) );                    
                }
                else if ( field.type == typeof( Vector3 ) )
                {
                    string[] split = sval.Split( ',' );
                    ( c as Vector3Field ).Value = new Vector3( float.Parse( split[ 0 ] ), float.Parse( split[ 1 ] ), float.Parse( split[ 2 ] ) );
                }
                else if ( field.type == typeof( Vector4 ) )
                {
                    string[] split = sval.Split( ',' );
                    ( c as Vector4Field ).Value = new Vector4( float.Parse( split[ 0 ] ), float.Parse( split[ 1 ] ), float.Parse( split[ 2 ] ), float.Parse( split[ 3 ] ) );
                }
                else if ( field.type == typeof( string ) )
                {
                    ( c as TextField ).Value = sval;
                }
                else if ( field.type == typeof( Rect ) )
                {
                    string[] split = sval.Split( ',' );
                    ( c as RectField ).Value = new Rect( float.Parse( split[ 0 ] ), float.Parse( split[ 1 ] ), float.Parse( split[ 2 ] ), float.Parse( split[ 3 ] ) );                    
                }
                else if ( field.type == typeof( Color ) )
                {
                    string[] split = sval.Split( ',' );
                    ( c as ColorField ).Value = new Color( float.Parse( split[ 0 ] ), float.Parse( split[ 1 ] ), float.Parse( split[ 2 ] ) );
                }
                else if ( field.type == typeof( Bounds ) )
                {
                    string[] split = sval.Split( ',' );
                    ( c as BoundsField ).Value = new Bounds( new Vector3( float.Parse( split[ 0 ] ), float.Parse( split[ 1 ] ), float.Parse( split[ 2 ] ) ),  new Vector3( float.Parse( split[ 3 ] ), float.Parse( split[ 4 ] ), float.Parse( split[ 5 ] ) ) );
                }
                else if ( field.type.IsEnum )
                {
                    System.Enum e = (System.Enum)System.Enum.Parse( field.type, sval );
                    ( c as EnumDropdown ).Value = e;
                }
                else if ( field.type == typeof( bool ) )
                {
                    ( c as Toggle ).Value = bool.Parse( sval );
                }
            }
        }
Beispiel #33
0
 public BehaviorTreeNodeIndexer(BehaviorNodeControl root)
 {
     m_indexTable = new Dictionary <BehaviorNodeControl, string>();
     IndexNode(root);
 }
        private bool CheckCircularReference( BehaviorNodeControl target, BehaviorNodeControl source )
        {
            if ( source == target )
            {
                return true;
            }

            foreach( BehaviorNodeControl child in source.m_outputs )
            {
                if ( CheckCircularReference( target, child ) )
                {
                    return true;
                }
            }

            return false;
        }
        public void SetOutput( BehaviorNodeControl target, int index )
        {
            // Not self
            if ( target == this )
            {
                return;
            }

            // Make sure connection does not already exist
            foreach( BehaviorNodeControl o in m_outputs )
            {
                if ( o == target )
                {
                    return;
                }
            }

            // Make sure there are no circular references
            foreach( BehaviorNodeControl o in target.m_outputs )
            {
                if ( CheckCircularReference( this, o ) )
                {
                    return;
                }
            }

            if ( index < m_outputs.Count )
            {
                // Replace
                m_outputs[ index ] = target;                
            }
            else
            {
                // New connection

                m_outputs.Add( target );
                BezierCurve line = (BezierCurve)m_canvas.AddShape( new BezierCurve( GetOutputConnectorPosition( index ), target.GetInputConnectorPosition(), Color.red, 1.0f, BezierCurve.TangentMode.AutoY, Vector2.zero, Vector2.zero ) );
                m_outputLines.Add( line );

                UpdateOutputs();
            }
        }
        private void DragHierarchy( BehaviorNodeControl c, Vector2 delta )
        {
            c.SetPosition( c.Position + delta );

            foreach( BehaviorNodeControl o in c.m_outputs )
            {
                if ( o != null )
                {
                    DragHierarchy( o, delta );
                }
            }
        }
        protected override void OnMouseDown( Event e )
        {
            switch( e.button )
            {
                case 0:
                    if ( m_linkFrom != null )
                    {
                        BehaviorNodeControl node = IsPointOnNode( e.mousePosition );
                        
                        if ( node != null )
                        {
                            m_linkFrom.SetOutput( node, m_linkFromIndex );
                        }

                        m_linkFrom = null;
                        m_linkLine.From = Vector2.zero;
                        m_linkLine.To = Vector2.zero;

                        e.Use();
                    }
                break;

                case 1:
                    if ( m_linkFrom != null )
                    {
                        m_linkFrom = null;
                        m_linkLine.From = Vector2.zero;
                        m_linkLine.To = Vector2.zero;

                        e.Use();
                    }
                break;
            }
        }
        private string GenerateNodeCode(BehaviorNodeControl node)
        {
            EditorCachedNode data = node.GetData();

            string s = "\n";

            s = string.Format("\t\t{0} {1} = new {0}( t );", data.type, m_indexTable[node]);

            foreach (EditorCachedNodeField field in data.fields)
            {
                if (node.m_fieldControls.ContainsKey(field.name))
                {
                    Control c = node.m_fieldControls[field.name];

                    if (field.type == typeof(int))
                    {
                        s += string.Format("\n\t\t{0}.{1} = {2};", m_indexTable[node], field.systemName, (c as IntField).Value);
                    }
                    else if (field.type == typeof(float))
                    {
                        s += string.Format("\n\t\t{0}.{1} = {2}f;", m_indexTable[node], field.systemName, (c as FloatField).Value);
                    }
                    else if (field.type == typeof(Vector2))
                    {
                        s += string.Format("\n\t\t{0}.{1} = new Vector2({2}f,{3}f);", m_indexTable[node], field.systemName, (c as Vector2Field).Value.x, (c as Vector2Field).Value.y);
                    }
                    else if (field.type == typeof(Vector3))
                    {
                        s += string.Format("\n\t\t{0}.{1} = new Vector3({2}f,{3}f,{4}f);", m_indexTable[node], field.systemName, (c as Vector3Field).Value.x, (c as Vector3Field).Value.y, (c as Vector3Field).Value.z);
                    }
                    else if (field.type == typeof(Vector4))
                    {
                        s += string.Format("\n\t\t{0}.{1} = new Vector4({2}f,{3}f,{4}f,{5}f);", m_indexTable[node], field.systemName, (c as Vector4Field).Value.x, (c as Vector4Field).Value.y, (c as Vector4Field).Value.z, (c as Vector4Field).Value.w);
                    }
                    else if (field.type == typeof(string))
                    {
                        s += string.Format("\n\t\t{0}.{1} = \"{2}\";", m_indexTable[node], field.systemName, (c as TextField).Value);
                    }
                    else if (field.type == typeof(Rect))
                    {
                        s += string.Format("\n\t\t{0}.{1} = new Rect({2}f,{3}f,{4}f,{5}f);", m_indexTable[node], field.systemName, (c as RectField).Value.xMin, (c as RectField).Value.yMin, (c as RectField).Value.width, (c as RectField).Value.height);
                    }
                    else if (field.type == typeof(Color))
                    {
                        s += string.Format("\n\t\t{0}.{1} = new Color({2},{3},{4},{5});", m_indexTable[node], field.systemName, (c as ColorField).Value.r, (c as ColorField).Value.g, (c as ColorField).Value.b, (c as ColorField).Value.a);
                    }
                    else if (field.type == typeof(Bounds))
                    {
                        s += string.Format("\n\t\t{0}.{1} = new Bounds( new Vector3({2}f,{3}f,{4}f),new Vector3({5}f,{6}f,{7}f));", m_indexTable[node], field.systemName, (c as BoundsField).Value.center.x, (c as BoundsField).Value.center.y, (c as BoundsField).Value.center.z, (c as BoundsField).Value.extents.x, (c as BoundsField).Value.extents.y, (c as BoundsField).Value.extents.z);
                    }
                    else if (field.type.IsEnum)
                    {
                        s += string.Format("\n\t\t{0}.{1} = {2}.{3};", m_indexTable[node], field.systemName, field.type.ToString().Replace("+", "."), (c as EnumDropdown).Value);
                    }
                    else if (field.type == typeof(bool))
                    {
                        s += string.Format("\n\t\t{0}.{1} = {2};", m_indexTable[node], field.systemName, (c as Toggle).Value.ToString().ToLowerInvariant());
                    }
                }
            }

            return(s);
        }
 private void SaveXML( string path, BehaviorNodeControl root )
 {
     BehaviorTreeXMLSerializer serializer = new BehaviorTreeXMLSerializer();
     string xml = serializer.Serialize( m_tools.TreeIdField.Value, root );
     File.WriteAllText( path, xml );
     AssetDatabase.Refresh();
 }
        private BehaviorNodeControl DeserializeNode( XmlNode xml, EditorNodeTypeCache typeCache, out string nodeId, out List<string> childIds )
        {
            childIds = new List<string>();

            nodeId           = xml.Attributes[ "id" ].InnerText;
            string type      = xml.Attributes[ "type" ].InnerText;
            string[] posStr  = xml.Attributes[ "position" ].InnerText.Split(',');
            Vector2 position = new Vector2( float.Parse( posStr[ 0 ] ), float.Parse( posStr[ 1 ] ) );

            if ( xml.Attributes[ "outputs" ] != null )
            {
                childIds.AddRange( xml.Attributes[ "outputs" ].InnerText.Split( ',' ) );
            }

            bool found = false;
            EditorCachedNode data = default(EditorCachedNode);

            foreach( EditorCachedNode cachedType in typeCache.Cache )
            {
                if ( cachedType.type.ToString() == type )
                {
                    found = true;
                    data = cachedType;
                    break;
                }
            }

            if ( !found )
            {                
                return null;
            }

            BehaviorNodeControl control = new BehaviorNodeControl( data );
            control.SetPosition( position );
            DeserializeFields( xml, data, control );

            return control;
        }
 public BehaviorTreeNodeIndexer( BehaviorNodeControl root )
 {
     m_indexTable = new Dictionary<BehaviorNodeControl, string>();
     IndexNode( root );
 }
        private string GenerateChildLinks( BehaviorNodeControl node )
        {
            string s = "";

            if ( node.m_outputs.Count > 0 )
            {
                s = "\n";
            }

            foreach( BehaviorNodeControl o in node.m_outputs )
            {
                s = string.Format( "{0}\t\t{1}.Children.Add({2});\n", s, m_indexTable[ node ], m_indexTable[ o ] );
            }

            return s;
        }