/// <summary>
        /// Deserialize a previously serialized game object.
        /// </summary>

        static public void Deserialize(this GameObject go, DataNode root, bool includeChildren = true)
        {
            DataNode resNode = root.GetChild("Resources");

            if (resNode != null)
            {
                for (int i = 0; i < resNode.children.size; ++i)
                {
                    DataNode child = resNode.children[i];
                    if (child.name == "Texture")
                    {
                        child.DeserializeTexture();
                    }
                    else if (child.name == "Material")
                    {
                        child.DeserializeMaterial();
                    }
                    else if (child.name == "Mesh")
                    {
                        child.DeserializeMesh();
                    }
                }
            }

            if (includeChildren)
            {
                go.DeserializeHierarchy(root);
                for (int i = 0; i < mSerList.size; ++i)
                {
                    mSerList[i].go.DeserializeComponents(mSerList[i].node);
                }
                mSerList.Clear();
            }
            else
            {
                go.DeserializeComponents(root);
            }
        }
        /// <summary>
        /// Deserialize a previously serialized material.
        /// </summary>

        static public Material DeserializeMaterial(this DataNode matNode)
        {
            Material mat = null;
            int      id  = matNode.Get <int>();

            if (mMaterials.TryGetValue(id, out mat) && mat != null)
            {
                return(mat);
            }

            // Try to load this material
            string name = matNode.GetChild <string>("name", "Unnamed");
            string path = matNode.GetChild <string>("path");

            if (id == 0)
            {
                id = (path + name).GetHashCode();
                if (mMaterials.TryGetValue(id, out mat) && mat != null)
                {
                    return(mat);
                }
            }

            if (!string.IsNullOrEmpty(path))
            {
                mat = UnityTools.Load <Material>(path);

                if (mat != null)
                {
                    mMaterials[id] = mat;
                    return(mat);
                }
            }

            // Material can only be created if there is a shader to work with
            string shaderName = matNode.GetChild <string>("shader");
            Shader shader     = Shader.Find(shaderName);

            if (shader == null)
            {
                Debug.LogWarning("Shader '" + shaderName + "' was not found");
                shader = Shader.Find("Diffuse");
            }

            // Create a new material
            mat            = new Material(shader);
            mat.name       = name;
            mMaterials[id] = mat;

            // Restore material properties
            for (int b = 0; b < matNode.children.size; ++b)
            {
                DataNode prop = matNode.children[b];
                if (prop.name == "shader")
                {
                    continue;
                }

                if (prop.children.size != 0)
                {
                    Texture tex = prop.DeserializeTexture();

                    if (tex != null)
                    {
                        mat.SetTexture(prop.name, tex);
                        mat.SetTextureOffset(prop.name, prop.GetChild <Vector2>("offset"));
                        mat.SetTextureScale(prop.name, prop.GetChild <Vector2>("scale", Vector2.one));
                    }
                }
                else if (prop.value is Vector4)
                {
                    mat.SetVector(prop.name, prop.Get <Vector4>());
                }
                else if (prop.value is Color)
                {
                    mat.SetColor(prop.name, prop.Get <Color>());
                }
                else if (prop.value is float || prop.value is int)
                {
                    mat.SetFloat(prop.name, prop.Get <float>());
                }
            }
            return(mat);
        }