/// <summary>
        /// Serialize the entire mesh into the specified DataNode.
        /// </summary>

        static public void Serialize(this Mesh mesh, DataNode node)
        {
            if (!mFullSerialization)
            {
                return;
            }

            node.AddChild("name", mesh.name);
            string path = UnityTools.LocateResource(mesh);

            if (!string.IsNullOrEmpty(path))
            {
                node.AddChild("path", path);
                return;
            }

            Add(node, "vertices", mesh.vertices);
            Add(node, "normals", mesh.normals);
            Add(node, "uv1", mesh.uv);
            Add(node, "uv2", mesh.uv2);
            Add(node, "tangents", mesh.tangents);
            Add(node, "colors", mesh.colors32);
            Add(node, "weights", mesh.boneWeights);
            Add(node, "poses", mesh.bindposes);
            Add(node, "triangles", mesh.triangles);
        }
Beispiel #2
0
 public virtual void Serialize(DataNode node)
 {
     node.AddChild("min", min);
     node.AddChild("max", max);
     node.AddChild("rate", rate);
     node.AddChild("value", value);
     node.AddChild("time", mTimestamp);
 }
        /// <summary>
        /// Serialize the specified renderer into its DataNode format.
        /// </summary>

        static void SerializeRenderer(Renderer ren, DataNode root)
        {
#if UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7
            root.AddChild("castShadows", ren.castShadows);
            if (ren.lightProbeAnchor != null)
            {
                root.AddChild("probeAnchor", ren.gameObject.ReferenceToString(ren.lightProbeAnchor));
            }
#else
            var sm = ren.shadowCastingMode;
            if (sm == UnityEngine.Rendering.ShadowCastingMode.Off)
            {
                root.AddChild("castShadows", false);
            }
            else if (sm == UnityEngine.Rendering.ShadowCastingMode.On)
            {
                root.AddChild("castShadows", true);
            }
            else
            {
                root.AddChild("shadowCasting", ren.shadowCastingMode);
            }
            root.AddChild("reflectionProbes", ren.reflectionProbeUsage);
            if (ren.probeAnchor != null)
            {
                root.AddChild("probeAnchor", ren.gameObject.ReferenceToString(ren.probeAnchor));
            }
#endif
            root.AddChild("receiveShadows", ren.receiveShadows);
            root.AddChild("useLightProbes", ren.useLightProbes);

            Material[] mats = ren.sharedMaterials;
            if (mats == null || mats.Length == 0)
            {
                return;
            }

            DataNode matNode = root.AddChild("Materials", mats.Length);

            for (int i = 0; i < mats.Length; ++i)
            {
                Material mat = mats[i];

                if (mat != null)
                {
                    DataNode node = matNode.AddChild("Material", mat.GetInstanceID());
                    mat.Serialize(node);
                }
            }
        }
 static void Add(DataNode node, string name, System.Array obj)
 {
     if (obj != null && obj.Length > 0)
     {
         node.AddChild(name, obj);
     }
 }
        /// <summary>
        /// Serialize the specified renderer into its DataNode format.
        /// </summary>

        static void Serialize(this SkinnedMeshRenderer ren, DataNode root)
        {
            Transform[] bones    = ren.bones;
            string[]    boneList = new string[bones.Length];
            for (int i = 0; i < bones.Length; ++i)
            {
                boneList[i] = ren.gameObject.ReferenceToString(bones[i]);
            }

            root.AddChild("root", ren.gameObject.ReferenceToString(ren.rootBone));
            root.AddChild("bones", boneList);

            Mesh sm = ren.sharedMesh;

            if (sm != null)
            {
                DataNode sub = root.AddChild("Mesh", sm.GetInstanceID());
                if (mFullSerialization)
                {
                    sm.Serialize(sub);
                }
            }

            root.AddChild("quality", ren.quality);
            root.AddChild("offscreen", ren.updateWhenOffscreen);
            root.AddChild("center", ren.localBounds.center);
            root.AddChild("size", ren.localBounds.size);

            SerializeRenderer(ren, root);
        }
        /// <summary>
        /// Serialize the Mesh Filter component.
        /// </summary>

        static public void Serialize(this MeshFilter filter, DataNode data)
        {
            Mesh sm = filter.sharedMesh;

            if (sm != null)
            {
                DataNode child = data.AddChild("Mesh", sm.GetInstanceID());
                sm.Serialize(child);
            }
        }
        /// <summary>
        /// Rigidbody class has a lot of properties that don't need to be serialized.
        /// </summary>

        static public void Serialize(this Rigidbody rb, DataNode node)
        {
            node.AddChild("mass", rb.mass);
            node.AddChild("drag", rb.drag);
            node.AddChild("angularDrag", rb.angularDrag);
            node.AddChild("interpolation", rb.interpolation);
            node.AddChild("collisionDetectionMode", rb.collisionDetectionMode);
            node.AddChild("isKinematic", rb.isKinematic);
            node.AddChild("useGravity", rb.useGravity);
        }
Beispiel #8
0
        /// <summary>
        /// Set a node's value given its hierarchical path.
        /// </summary>

        public DataNode SetHierarchy(string path, object obj)
        {
            DataNode node = this;

            if (!string.IsNullOrEmpty(path))
            {
                if (path.IndexOf('\\') == -1 && path.IndexOf('/') == -1)
                {
                    if (obj == null)
                    {
                        RemoveChild(path);
                        return(null);
                    }

                    node = GetChild(path, true);
                }
                else
                {
                    path = path.Replace("\\", "/");
                    string[] names  = path.Split('/');
                    DataNode parent = null;
                    int      index  = 0;

                    while (node != null && index < names.Length)
                    {
                        bool found = false;

                        for (int i = 0; i < node.children.size; ++i)
                        {
                            if (node.children[i].name == names[index])
                            {
                                parent = node;
                                node   = node.children[i];
                                ++index;
                                found = true;
                                break;
                            }
                        }

                        if (!found)
                        {
                            if (obj == null)
                            {
                                break;
                            }
                            parent = node;
                            node   = node.AddChild(names[index]);
                            ++index;
                        }
                    }

                    if (obj == null)
                    {
                        if (parent != null)
                        {
                            parent.RemoveChild(names[index - 1]);
                        }
                        return(parent);
                    }
                }
            }

            if (obj is DataNode)
            {
                DataNode other = (obj as DataNode);
                node.value = other.value;
                node.children.Clear();
                for (int i = 0; i < other.children.size; ++i)
                {
                    node.children.Add(other.children[i].Clone());
                }
            }
            else
            {
                node.value = obj;
            }
            return(node);
        }
        /// <summary>
        /// Collect all meshes, materials and textures underneath the specified object and serialize them into the DataNode.
        /// </summary>

        static public void SerializeSharedResources(this GameObject go, DataNode node, bool includeInactive = false)
        {
            mFullSerialization = true;

            MeshFilter[]          filters = go.GetComponentsInChildren <MeshFilter>(includeInactive);
            MeshRenderer[]        rens    = go.GetComponentsInChildren <MeshRenderer>(includeInactive);
            SkinnedMeshRenderer[] sks     = go.GetComponentsInChildren <SkinnedMeshRenderer>(includeInactive);

            List <Material> materials = new List <Material>();
            List <Mesh>     meshes    = new List <Mesh>();

            foreach (MeshFilter f in filters)
            {
                Mesh m = f.sharedMesh;
                if (!meshes.Contains(m))
                {
                    meshes.Add(m);
                }
            }

            foreach (SkinnedMeshRenderer sk in sks)
            {
                Mesh m = sk.sharedMesh;
                if (!meshes.Contains(m))
                {
                    meshes.Add(m);
                }

                Material[] mats = sk.sharedMaterials;
                foreach (Material mt in mats)
                {
                    if (!materials.Contains(mt))
                    {
                        materials.Add(mt);
                    }
                }
            }

            foreach (MeshRenderer r in rens)
            {
                Material[] mats = r.sharedMaterials;
                foreach (Material m in mats)
                {
                    if (!materials.Contains(m))
                    {
                        materials.Add(m);
                    }
                }
            }

            if (materials.size == 0 && meshes.size == 0)
            {
                return;
            }

#if UNITY_EDITOR
            List <Texture> textures = new List <Texture>();

            for (int i = 0; i < materials.size; ++i)
            {
                Material mat = materials[i];
                Shader   s   = mat.shader;
                if (s == null)
                {
                    continue;
                }

                string matPath = UnityTools.LocateResource(mat);
                if (!string.IsNullOrEmpty(matPath))
                {
                    continue;
                }

                int props = UnityEditor.ShaderUtil.GetPropertyCount(s);

                for (int b = 0; b < props; ++b)
                {
                    string propName = UnityEditor.ShaderUtil.GetPropertyName(s, b);
                    UnityEditor.ShaderUtil.ShaderPropertyType type = UnityEditor.ShaderUtil.GetPropertyType(s, b);
                    if (type != UnityEditor.ShaderUtil.ShaderPropertyType.TexEnv)
                    {
                        continue;
                    }
                    Texture tex = mat.GetTexture(propName);
                    if (tex != null && !textures.Contains(tex))
                    {
                        textures.Add(tex);
                    }
                }
            }

            for (int i = 0; i < textures.size; ++i)
            {
                Texture tex = textures[i];
                tex.Serialize(node.AddChild("Texture", tex.GetInstanceID()));
            }
#endif

            for (int i = 0; i < materials.size; ++i)
            {
                Material mat = materials[i];
                mat.Serialize(node.AddChild("Material", mat.GetInstanceID()), false);
            }

            for (int i = 0; i < meshes.size; ++i)
            {
                Mesh mesh = meshes[i];
                mesh.Serialize(node.AddChild("Mesh", mesh.GetInstanceID()));
            }
        }
        /// <summary>
        /// Serialize the entire texture into the specified DataNode.
        /// </summary>

        static public void Serialize(this Texture tex, DataNode node)
        {
            if (!mFullSerialization)
            {
                return;
            }

            node.AddChild("name", tex.name);
            string path = UnityTools.LocateResource(tex);

            if (!string.IsNullOrEmpty(path))
            {
                node.AddChild("path", path);
                return;
            }

            if (tex is Texture2D)
            {
                Texture2D t2 = tex as Texture2D;

#if UNITY_EDITOR
                try
                {
                    byte[] bytes = t2.EncodeToPNG();
                    if (bytes != null)
                    {
                        node.AddChild("bytes", bytes);
                    }
                    else
                    {
                        Debug.Log(t2.name + " (" + t2.format + ")", tex);
                    }
                }
                catch (Exception)
                {
                    string assetPath = UnityEditor.AssetDatabase.GetAssetPath(tex);

                    if (!string.IsNullOrEmpty(assetPath))
                    {
                        UnityEditor.TextureImporter ti = UnityEditor.AssetImporter.GetAtPath(assetPath) as UnityEditor.TextureImporter;
                        ti.isReadable = true;
                        UnityEditor.AssetDatabase.ImportAsset(assetPath);
                        byte[] bytes = t2.EncodeToPNG();
                        if (bytes != null)
                        {
                            node.AddChild("bytes", bytes);
                        }
                        else
                        {
                            Debug.Log(t2.name + " (" + t2.format + ")", tex);
                        }
                    }
                }
#else
                node.AddChild("bytes", t2.EncodeToPNG());
#endif
                node.AddChild("filter", (int)t2.filterMode);
                node.AddChild("wrap", (int)t2.wrapMode);
                node.AddChild("af", t2.anisoLevel);
                return;
            }

            Debug.LogWarning("Unable to save a reference to texture '" + tex.name + "' because it's not in the Resources folder.", tex);
        }
        /// <summary>
        /// Serialize the specified material into its DataNode format.
        /// </summary>

        static public void Serialize(this Material mat, DataNode node, bool serializeTextures)
        {
            if (!mFullSerialization)
            {
                return;
            }

            node.AddChild("name", mat.name);
            string path = UnityTools.LocateResource(mat);

            if (!string.IsNullOrEmpty(path))
            {
                node.AddChild("path", path);
                return;
            }

            Shader s = mat.shader;

            if (s != null)
            {
                node.AddChild("shader", s.name);
#if UNITY_EDITOR
                int props = UnityEditor.ShaderUtil.GetPropertyCount(s);

                for (int b = 0; b < props; ++b)
                {
                    string propName = UnityEditor.ShaderUtil.GetPropertyName(s, b);
                    UnityEditor.ShaderUtil.ShaderPropertyType type = UnityEditor.ShaderUtil.GetPropertyType(s, b);

                    if (type == UnityEditor.ShaderUtil.ShaderPropertyType.Color)
                    {
                        node.AddChild(propName, mat.GetColor(propName));
                    }
                    else if (type == UnityEditor.ShaderUtil.ShaderPropertyType.Vector)
                    {
                        node.AddChild(propName, mat.GetVector(propName));
                    }
                    else if (type == UnityEditor.ShaderUtil.ShaderPropertyType.TexEnv)
                    {
                        Texture tex = mat.GetTexture(propName);

                        if (tex != null)
                        {
                            DataNode sub = new DataNode(propName, tex.GetInstanceID());
                            if (serializeTextures)
                            {
                                tex.Serialize(sub);
                            }
                            sub.AddChild("offset", mat.GetTextureOffset(propName));
                            sub.AddChild("scale", mat.GetTextureScale(propName));
                            node.children.Add(sub);
                        }
                    }
                    else
                    {
                        node.AddChild(propName, mat.GetFloat(propName));
                    }
                }
#endif
            }
        }
        /// <summary>
        /// Generic component serialization function. You can add custom serialization
        /// to any component by adding an extension with this signature:
        /// static public void Serialize (this YourComponentType, DataNode);
        /// </summary>

        static public void Serialize(this Component c, DataNode node, Type type = null)
        {
            // The 'enabled' flag should only be written down if the behavior is actually disabled
            Behaviour b = c as Behaviour;

            if (b != null)
            {
                if (!b.enabled)
                {
                    node.AddChild("enabled", b.enabled);
                }
            }
            else
            {
                Collider cd = c as Collider;
                if (cd != null && !cd.enabled)
                {
                    node.AddChild("enabled", cd.enabled);
                }
            }

            // Try custom serialization first
            if (c.Invoke("Serialize", node))
            {
                return;
            }

            GameObject go = c.gameObject;

            if (type == null)
            {
                type = c.GetType();
            }
            MonoBehaviour mb = c as MonoBehaviour;

            if (mb != null)
            {
                // For MonoBehaviours we want to serialize serializable fields
                List <FieldInfo> fields = type.GetSerializableFields();

                for (int f = 0; f < fields.size; ++f)
                {
                    FieldInfo field = fields[f];

                    object val = field.GetValue(c);
                    if (val == null)
                    {
                        continue;
                    }

                    val = EncodeReference(go, val);
                    if (val == null)
                    {
                        continue;
                    }

                    node.AddChild(field.Name, val);
                }
            }
            else
            {
                // Unity components don't have fields, so we should serialize properties instead.
                List <PropertyInfo> props = type.GetSerializableProperties();

                for (int f = 0; f < props.size; ++f)
                {
                    PropertyInfo prop = props[f];

                    if (prop.Name == "name" ||
                        prop.Name == "tag" ||
                        prop.Name == "hideFlags" ||
                        prop.Name == "enabled" ||
                        prop.Name == "material" ||
                        prop.Name == "materials")
                    {
                        continue;
                    }

                    object val = prop.GetValue(c, null);
                    if (val == null)
                    {
                        continue;
                    }

                    val = EncodeReference(go, val);
                    if (val == null)
                    {
                        continue;
                    }

                    node.AddChild(prop.Name, val);
                }
            }
        }
        /// <summary>
        /// Camera serialization skips a bunch of values such as "layerCullDistances", "stereoSeparation", and more.
        /// </summary>

        static public void Serialize(this Camera cam, DataNode node)
        {
            node.AddChild("clearFlags", cam.clearFlags);
            node.AddChild("backgroundColor", cam.backgroundColor);
            node.AddChild("cullingMask", cam.cullingMask);
            node.AddChild("orthographic", cam.orthographic);
            node.AddChild("orthographicSize", cam.orthographicSize);
            node.AddChild("fieldOfView", cam.fieldOfView);
            node.AddChild("nearClipPlane", cam.nearClipPlane);
            node.AddChild("farClipPlane", cam.farClipPlane);
            node.AddChild("rect", cam.rect);
            node.AddChild("depth", cam.depth);
            node.AddChild("renderingPath", cam.renderingPath);
            node.AddChild("useOcclusionCulling", cam.useOcclusionCulling);
            node.AddChild("hdr", cam.hdr);
        }
        /// <summary>
        /// Serialize this game object into a DataNode.
        /// Note that the prefab references can only be resolved if serialized from within the Unity Editor.
        /// You can instantiate this game object directly from DataNode format by using DataNode.Instantiate().
        /// Ideal usage: save a game object hierarchy into a file. Serializing a game object will also serialize its
        /// mesh data, making it possible to export entire 3D models. Any references to prefabs or materials located
        /// in the Resources folder will be kept as references and their hierarchy won't be serialized.
        /// </summary>

        static public DataNode Serialize(this GameObject go, bool fullHierarchy = true, bool isRootNode = true)
        {
            DataNode root = new DataNode(go.name, go.GetInstanceID());

            // Save a reference to a prefab, if there is one
            string prefab = UnityTools.LocateResource(go, !isRootNode);

            if (!string.IsNullOrEmpty(prefab))
            {
                root.AddChild("prefab", prefab);
            }

            // Save the transform and the object's layer
            Transform trans = go.transform;

            root.AddChild("position", trans.localPosition);
            root.AddChild("rotation", trans.localEulerAngles);
            root.AddChild("scale", trans.localScale);

            int layer = go.layer;

            if (layer != 0)
            {
                root.AddChild("layer", go.layer);
            }

            // If this was a prefab instance, don't do anything else
            if (!string.IsNullOrEmpty(prefab))
            {
                return(root);
            }

            // Collect all meshes
            if (isRootNode)
            {
                DataNode child = new DataNode("Resources");
#if UNITY_EDITOR
                go.SerializeSharedResources(child, UnityEditor.PrefabUtility.GetPrefabType(go) == UnityEditor.PrefabType.Prefab);
#else
                go.SerializeSharedResources(child);
#endif
                if (child.children.size != 0)
                {
                    root.children.Add(child);
                }
                mFullSerialization = false;
            }

            Component[] comps    = go.GetComponents <Component>();
            DataNode    compRoot = null;

            for (int i = 0, imax = comps.Length; i < imax; ++i)
            {
                Component c = comps[i];

                System.Type type = c.GetType();
                if (type == typeof(Transform))
                {
                    continue;
                }

                if (compRoot == null)
                {
                    compRoot = root.AddChild("Components");
                }
                DataNode child = compRoot.AddChild(Serialization.TypeToName(type), c.GetInstanceID());
                c.Serialize(child, type);
            }

            if (fullHierarchy && trans.childCount > 0)
            {
                DataNode children = root.AddChild("Children");

                for (int i = 0, imax = trans.childCount; i < imax; ++i)
                {
                    GameObject child = trans.GetChild(i).gameObject;
                    if (child.activeInHierarchy)
                    {
                        children.children.Add(child.Serialize(true, false));
                    }
                }
            }
            if (isRootNode)
            {
                mFullSerialization = true;
            }
            return(root);
        }