/// <summary> /// Generic deserialization function. You can create a custom deserialization /// for your components by adding an extension method with this signature: /// static public void Deserialize (this YourComponentType, DataNode); /// </summary> static public void Deserialize(this Component c, DataNode node) { Behaviour b = c as Behaviour; if (b != null) { b.enabled = node.GetChild <bool>("enabled", b.enabled); } else { Collider cd = c as Collider; if (cd != null) { cd.enabled = node.GetChild <bool>("enabled", cd.enabled); } } // Try calling the custom function first if (c.Invoke("Deserialize", node)) { return; } GameObject go = c.gameObject; // Fallback -- just set the appropriate fields/properties for (int i = 0; i < node.children.size; ++i) { DataNode child = node.children[i]; if (child.value != null) { c.SetFieldOrPropertyValue(child.name, child.value, go); } } }
/// <summary> /// Instantiate a new game object given its previously serialized DataNode. /// You can serialize game objects by using GameObject.Serialize(), but be aware that serializing only /// works fully in the Unity Editor. Prefabs can't be located automatically outside of the Unity Editor. /// </summary> static public GameObject Instantiate(this DataNode data) { GameObject child = null; byte[] assetBytes = data.GetChild <byte[]>("assetBundle"); if (assetBytes != null) { GameObject prefab; if (!mCachedBundles.TryGetValue(assetBytes, out prefab)) { #if UNITY_4_6 || UNITY_4_7 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2 AssetBundle qr = AssetBundle.CreateFromMemoryImmediate(assetBytes); #else AssetBundle qr = AssetBundle.LoadFromMemory(assetBytes); #endif if (qr != null) { prefab = qr.mainAsset as GameObject; } if (prefab == null) { prefab = new GameObject(data.name); } mCachedBundles[assetBytes] = prefab; } child = GameObject.Instantiate(prefab) as GameObject; child.name = data.name; } else { string path = data.GetChild <string>("prefab"); if (!string.IsNullOrEmpty(path)) { GameObject prefab = UnityTools.LoadPrefab(path); if (prefab != null) { child = GameObject.Instantiate(prefab) as GameObject; child.name = data.name; child.SetActive(true); } else { child = new GameObject(data.name); } } else { child = new GameObject(data.name); } child.Deserialize(data, true); } return(child); }
public virtual void Deserialize(DataNode node) { min = node.GetChild <double>("min"); max = node.GetChild <double>("max"); rate = node.GetChild <double>("rate"); mValue = node.GetChild <double>("value"); mTimestamp = node.GetChild <long>("time"); }
/// <summary> /// Instantiate a new game object given its previously serialized DataNode. /// You can serialize game objects by using GameObject.Serialize(), but be aware that serializing only /// works fully in the Unity Editor. Prefabs can't be located automatically outside of the Unity Editor. /// </summary> static public GameObject Instantiate(this DataNode data) { GameObject child = null; byte[] assetBytes = data.GetChild <byte[]>("assetBundle"); if (assetBytes != null) { AssetBundle ab = UnityTools.LoadAssetBundle(assetBytes); if (ab != null) { var go = ab.mainAsset as GameObject; if (go != null) { child = GameObject.Instantiate(go) as GameObject; child.name = data.name; } } } else { string path = data.GetChild <string>("prefab"); if (!string.IsNullOrEmpty(path)) { GameObject prefab = UnityTools.LoadPrefab(path); if (prefab != null) { child = GameObject.Instantiate(prefab) as GameObject; child.name = data.name; child.SetActive(true); } else { child = new GameObject(data.name); } } else { child = new GameObject(data.name); } child.Deserialize(data, true); } return(child); }
/// <summary> /// Deserialize a previously serialized game object. /// </summary> static void DeserializeComponents(this GameObject go, DataNode root) { DataNode scriptNode = root.GetChild("Components"); if (scriptNode == null) { return; } for (int i = 0; i < scriptNode.children.size; ++i) { DataNode node = scriptNode.children[i]; System.Type type = UnityTools.GetType(node.name); if (type != null && type.IsSubclassOf(typeof(Component))) { Component comp = go.GetComponent(type); if (comp == null) { comp = go.AddComponent(type); } comp.Deserialize(node); } } }
/// <summary> /// Deserialize a previously serialized renderer. /// </summary> static public void Deserialize(this Renderer ren, DataNode data) { #if UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 ren.castShadows = data.GetChild <bool>("castShadows", ren.castShadows); #else DataNode cs = data.GetChild("castShadows"); if (cs != null) { ren.shadowCastingMode = cs.Get <bool>() ? UnityEngine.Rendering.ShadowCastingMode.On : UnityEngine.Rendering.ShadowCastingMode.Off; } else { ren.shadowCastingMode = data.GetChild <UnityEngine.Rendering.ShadowCastingMode>("shadowCastingMode", ren.shadowCastingMode); } ren.reflectionProbeUsage = data.GetChild <UnityEngine.Rendering.ReflectionProbeUsage>("reflectionProbes", ren.reflectionProbeUsage); #endif ren.receiveShadows = data.GetChild <bool>("receiveShadows", ren.receiveShadows); #if UNITY_4_7 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 ren.useLightProbes = data.GetChild <bool>("useLightProbes", ren.useLightProbes); #else var lpu = data.GetChild("lightProbeUsage"); if (lpu != null) { ren.lightProbeUsage = (UnityEngine.Rendering.LightProbeUsage)lpu.Get <byte>((byte)ren.lightProbeUsage); } else { // Pre-Unity 5.4 format ren.lightProbeUsage = data.GetChild <bool>("useLightProbes", ren.lightProbeUsage != UnityEngine.Rendering.LightProbeUsage.Off) ? UnityEngine.Rendering.LightProbeUsage.BlendProbes : UnityEngine.Rendering.LightProbeUsage.Off; } #endif DataNode matRoot = data.GetChild("Materials"); if (matRoot != null && matRoot.children.size > 0) { Material[] mats = new Material[matRoot.children.size]; for (int i = 0; i < matRoot.children.size; ++i) { DataNode matNode = matRoot.children[i]; mats[i] = matNode.DeserializeMaterial(); } ren.sharedMaterials = mats; } }
/// <summary> /// Restore a previously serialized Mesh Filter component. /// </summary> static public void Deserialize(this MeshFilter filter, DataNode data) { DataNode mesh = data.GetChild("Mesh"); if (mesh != null) { filter.sharedMesh = mesh.DeserializeMesh(); } }
/// <summary> /// Deserialize a previously serialized game object. /// </summary> static void DeserializeHierarchy(this GameObject go, DataNode root) { SerializationEntry ent = new SerializationEntry(); ent.go = go; ent.node = root; mSerList.Add(ent); Transform trans = go.transform; trans.localPosition = root.GetChild <Vector3>("position", trans.localPosition); trans.localEulerAngles = root.GetChild <Vector3>("rotation", trans.localEulerAngles); trans.localScale = root.GetChild <Vector3>("scale", trans.localScale); go.layer = root.GetChild <int>("layer", go.layer); DataNode childNode = root.GetChild("Children"); if (childNode != null && childNode.children.size > 0) { for (int i = 0; i < childNode.children.size; ++i) { DataNode node = childNode.children[i]; GameObject child = null; GameObject prefab = UnityTools.Load <GameObject>(node.GetChild <string>("prefab")); if (prefab != null) { child = GameObject.Instantiate(prefab) as GameObject; } if (child == null) { child = new GameObject(); } child.name = node.name; Transform t = child.transform; t.parent = trans; t.localPosition = Vector3.zero; t.localRotation = Quaternion.identity; t.localScale = Vector3.one; child.DeserializeHierarchy(node); } } }
/// <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 renderer. /// </summary> static void Deserialize(this SkinnedMeshRenderer ren, DataNode data) { GameObject go = ren.gameObject; ren.rootBone = go.StringToReference(data.GetChild <string>("root")) as Transform; string[] boneList = data.GetChild <string[]>("bones"); if (boneList != null) { Transform[] bones = new Transform[boneList.Length]; for (int i = 0; i < bones.Length; ++i) { bones[i] = go.StringToReference(boneList[i]) as Transform; if (bones[i] == null) { Debug.LogWarning("Bone not found: " + boneList[i], go); } } ren.bones = bones; } DataNode meshNode = data.GetChild("Mesh"); if (meshNode != null) { ren.sharedMesh = meshNode.DeserializeMesh(); } ren.quality = data.GetChild <SkinQuality>("quality", ren.quality); ren.updateWhenOffscreen = data.GetChild <bool>("offscreen", ren.updateWhenOffscreen); Vector3 center = data.GetChild <Vector3>("center", ren.localBounds.center); Vector3 size = data.GetChild <Vector3>("size", ren.localBounds.size); ren.localBounds = new Bounds(center, size); Deserialize((Renderer)ren, data); }
/// <summary> /// Deserialize a previously serialized renderer. /// </summary> static public void Deserialize(this Renderer ren, DataNode data) { #if UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 ren.castShadows = data.GetChild <bool>("castShadows", ren.castShadows); #else DataNode cs = data.GetChild("castShadows"); if (cs != null) { ren.shadowCastingMode = cs.Get <bool>() ? UnityEngine.Rendering.ShadowCastingMode.On : UnityEngine.Rendering.ShadowCastingMode.Off; } else { ren.shadowCastingMode = data.GetChild <UnityEngine.Rendering.ShadowCastingMode>("shadowCastingMode", ren.shadowCastingMode); } ren.reflectionProbeUsage = data.GetChild <UnityEngine.Rendering.ReflectionProbeUsage>("reflectionProbes", ren.reflectionProbeUsage); #endif ren.receiveShadows = data.GetChild <bool>("receiveShadows", ren.receiveShadows); ren.useLightProbes = data.GetChild <bool>("useLightProbes", ren.useLightProbes); DataNode matRoot = data.GetChild("Materials"); if (matRoot != null && matRoot.children.size > 0) { Material[] mats = new Material[matRoot.children.size]; for (int i = 0; i < matRoot.children.size; ++i) { DataNode matNode = matRoot.children[i]; mats[i] = matNode.DeserializeMaterial(); } ren.sharedMaterials = mats; } }
/// <summary> /// Deserialize the texture that was previously serialized into the DataNode format. /// </summary> static public Texture DeserializeTexture(this DataNode node) { // First try the cache Texture tex = null; int id = node.Get <int>(); if (id != 0 && mTextures.TryGetValue(id, out tex) && tex != null) { return(tex); } // If the texture's ID is unknown, make a dummy one and try going through cache again string name = node.GetChild <string>("name", "Unnamed"); string path = node.GetChild <string>("path"); if (id == 0) { id = (path + name).GetHashCode(); if (mTextures.TryGetValue(id, out tex) && tex != null) { return(tex); } } // Next try to load the texture if (!string.IsNullOrEmpty(path)) { tex = UnityTools.Load <Texture>(path); if (tex != null) { mTextures[id] = tex; return(tex); } } // Lastly, create a new texture Texture2D t2 = new Texture2D(2, 2); t2.name = name; // Try to load the texture's data byte[] bytes = node.GetChild <byte[]>("bytes"); if (bytes != null) { t2.LoadImage(bytes); t2.filterMode = (FilterMode)node.GetChild <int>("filter", (int)t2.filterMode); t2.wrapMode = (TextureWrapMode)node.GetChild <int>("wrap", (int)t2.wrapMode); t2.anisoLevel = node.GetChild <int>("af", t2.anisoLevel); t2.Apply(); } else { #if UNITY_EDITOR Debug.LogWarning("Creating a dummy texture: " + t2.name, t2); #endif t2.SetPixels(new Color[] { Color.clear, Color.clear, Color.clear, Color.clear }); t2.Apply(); } // Add it to cache tex = t2; mTextures[id] = tex; return(tex); }
/// <summary> /// Set the mesh from the specified DataNode. /// </summary> static public Mesh DeserializeMesh(this DataNode node) { Mesh mesh = null; int id = node.Get <int>(); if (id != 0 && mCachedMeshes.TryGetValue(id, out mesh) && mesh != null) { return(mesh); } string name = node.GetChild <string>("name"); string path = node.GetChild <string>("path"); if (id == 0) { id = (path + name).GetHashCode(); if (mCachedMeshes.TryGetValue(id, out mesh) && mesh != null) { return(mesh); } } if (!string.IsNullOrEmpty(path)) { mesh = UnityTools.Load <Mesh>(path, name); #if UNITY_EDITOR if (mesh == null) { Debug.LogWarning("Unable to find mesh '" + name + "' in " + path); } #endif } else { mesh = new Mesh(); mesh.name = name; Vector3[] verts = node.GetChild <Vector3[]>("vertices"); if (verts != null) { mesh.vertices = verts; } Vector3[] normals = node.GetChild <Vector3[]>("normals"); if (normals != null) { mesh.normals = normals; } Vector2[] uv1 = node.GetChild <Vector2[]>("uv1"); if (uv1 != null) { mesh.uv = uv1; } Vector2[] uv2 = node.GetChild <Vector2[]>("uv2"); if (uv2 != null) { mesh.uv2 = uv2; } Vector4[] tangents = node.GetChild <Vector4[]>("tangents"); if (tangents != null) { mesh.tangents = tangents; } Color32[] colors = node.GetChild <Color32[]>("colors"); if (colors != null) { mesh.colors32 = colors; } BoneWeight[] weights = node.GetChild <BoneWeight[]>("weights"); if (weights != null) { mesh.boneWeights = weights; } Matrix4x4[] poses = node.GetChild <Matrix4x4[]>("poses"); if (poses != null) { mesh.bindposes = poses; } int[] triangles = node.GetChild <int[]>("triangles"); if (triangles != null) { mesh.triangles = triangles; } mesh.RecalculateBounds(); } mCachedMeshes[id] = mesh; return(mesh); }
/// <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); }