public override void Deserialize(Dictionary <PCFResourceType, DataBlockBase> dataBlocks, UnityNodeBase parentNode, ResourceResponse resourceResponse, List <Action <UnityNodeBase> > postInstallActions, bool optimizedLoad) { if (!this.isDeserialized) { ResourceBlock dataBlock = dataBlocks[this.resourceType] as ResourceBlock; AssetResource resource = dataBlock.GetResource(this.referenceID); System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); byte[] metaDataBuffer = resource.GetMetaData(); SerializedMaterial serializedMaterial = ProtocolBufferSerializer.DeserializeMaterialData(metaDataBuffer); string shaderName = serializedMaterial.ShaderName; this.material = new UnityEngine.Material(Shader.Find(shaderName)); this.material.name = serializedMaterial.DisplayName; ResourceResponse previousRequest = null; if (serializedMaterial.MaterialProperties != null) { foreach (KeyValuePair <string, SerializedMaterialProperty> pair in serializedMaterial.MaterialProperties) { if (pair.Value != null) { MaterialPropertyType propertyType = (MaterialPropertyType)pair.Value.PropertyType; if (propertyType == MaterialPropertyType.FloatType) { SerializedMaterialFloatProperty floatProperty = pair.Value as SerializedMaterialFloatProperty; this.material.SetFloat(pair.Key, floatProperty.Val); } else if (propertyType == MaterialPropertyType.VectorType) { SerializedMaterialVectorProperty vectorProperty = pair.Value as SerializedMaterialVectorProperty; Vector4 vector = new Vector4(vectorProperty.X, vectorProperty.Y, vectorProperty.Z, vectorProperty.W); this.material.SetVector(pair.Key, vector); } else if (propertyType == MaterialPropertyType.ColorType) { SerializedMaterialColorProperty colorProperty = pair.Value as SerializedMaterialColorProperty; Color color = new Color(colorProperty.R, colorProperty.G, colorProperty.B, colorProperty.A); this.material.SetColor(pair.Key, color); } else if (propertyType == MaterialPropertyType.TextureType) { SerializedMaterialTextureProperty textureProperty = pair.Value as SerializedMaterialTextureProperty; string propertyName = pair.Key; ResourceResponse textureRequest = new ResourceResponse(textureProperty.ReferenceID, (ResourceResponse response) => { material.SetTexture(propertyName, response.GetTextureRequest); }); if (previousRequest != null) { textureRequest.SetPreviousResponse(previousRequest); previousRequest.SetNextResponse(textureRequest); } previousRequest = textureRequest; } } } } if (previousRequest != null) { //Get the first request created. ResourceResponse firstRequest = previousRequest; while (true) { ResourceResponse previous = firstRequest.GetPreviousResponse(); if (previous == null) { break; } firstRequest = previous; } //Have each request set by one of the child nodes. for (int i = 0; i < this.ChildNodes.Count; i++) { UnityNodeBase child = this.ChildNodes[i]; child.Deserialize(dataBlocks, parentNode, firstRequest, postInstallActions, optimizedLoad); } } //Finish up and set material to whatever field/object that owns this node. ResourceResponse request = resourceResponse.CanHandle(GetReferenceID()); if (request != null) { request.HandleMaterialResponse(this.material); } watch.Stop(); //Debug.Log("Time to deserialize material: " + watch.ElapsedMilliseconds); this.isDeserialized = true; } }
public override void Serialize(SerializedAssets serializedAssets, object[] serializeOptions, NodeBase objNode, List <Action <NodeBase> > postSerializeActions) { #if UNITY_EDITOR //Make sure this is always 36 characters long. this.referenceID = this.rootNode.GenerateID(); //Check if node hierarchy contains this material already. string path = AssetDatabase.GetAssetPath(this.material); NodeBase materialNode = CheckSharedMaterial(this.rootNode, path); //If material is already serialized (aka shared we simply serialize a pointer to it. if (materialNode != null) { //Debug.Log("Shared Material: " + path); UInt32 materialID = materialNode.GetReferenceID(); ComponentNode componentNode = new ComponentNode(PCFResourceType.MATERIALPOINTER, referenceID, null); objNode.AddChildNode(componentNode); byte[] bytes = BitConverter.GetBytes(materialID); //Create serialized asset by converting data to a bytearray and give it to the constructor. AssetResource resource = new AssetResource(false); resource.Serialize(referenceID, MetaDataType.UNKOWN, null, bytes); serializedAssets.AddResource(referenceID, PCFResourceType.MATERIALPOINTER, resource); //Make sure caller can get the actual material referenceID when serializing its metadata. this.pointedID = materialID; } else { ComponentNode componentNode = new ComponentNode(PCFResourceType.MATERIAL, referenceID, path); //Material nodes can and are most likely to be children of other component nodes. objNode.AddChildNode(componentNode); SerializedMaterial serializedMaterial = new SerializedMaterial(); serializedMaterial.DisplayName = this.material.name; serializedMaterial.ShaderName = this.material.shader.name; Dictionary <string, SerializedMaterialProperty> materialProperties = new Dictionary <string, SerializedMaterialProperty>(); // Iterate through children and get the textures of the material. Shader shader = this.material.shader; int count = ShaderUtil.GetPropertyCount(shader); for (int i = 0; i < count; i++) { ShaderUtil.ShaderPropertyType propertyType = ShaderUtil.GetPropertyType(shader, i); string propertyName = ShaderUtil.GetPropertyName(shader, i); SerializedMaterialProperty property = null; //Color property. if (propertyType == ShaderUtil.ShaderPropertyType.Float || propertyType == ShaderUtil.ShaderPropertyType.Range) { SerializedMaterialFloatProperty prop = new SerializedMaterialFloatProperty(); prop.Val = this.material.GetFloat(propertyName); prop.PropertyType = (int)MaterialPropertyType.FloatType; property = prop; } //Vector property. if (propertyType == ShaderUtil.ShaderPropertyType.Vector) { SerializedMaterialVectorProperty prop = new SerializedMaterialVectorProperty(); Vector4 vector = this.material.GetVector(propertyName); prop.X = vector.x; prop.Y = vector.y; prop.Z = vector.z; prop.W = vector.w; prop.PropertyType = (int)MaterialPropertyType.VectorType; property = prop; } //Float property. if (propertyType == ShaderUtil.ShaderPropertyType.Color) { SerializedMaterialColorProperty prop = new SerializedMaterialColorProperty(); Color color = this.material.GetColor(propertyName); prop.R = color.r; prop.G = color.g; prop.B = color.b; prop.A = color.a; prop.PropertyType = (int)MaterialPropertyType.ColorType; property = prop; } //Texture property. if (propertyType == ShaderUtil.ShaderPropertyType.TexEnv) { Texture2D texture = (Texture2D)this.material.GetTexture(propertyName); if (texture != null) { UnitySerializeTexture textureSerializer = new UnitySerializeTexture(texture, this.rootNode); textureSerializer.Serialize(serializedAssets, serializeOptions, componentNode, postSerializeActions); SerializedMaterialTextureProperty prop = new SerializedMaterialTextureProperty(); prop.ReferenceID = textureSerializer.GetReferenceID(); prop.PropertyType = (int)MaterialPropertyType.TextureType; property = prop; } } materialProperties.Add(propertyName, property); } serializedMaterial.MaterialProperties = materialProperties; //Create serialized asset by converting data to a bytearray and give it to the constructor. AssetResource resource = new AssetResource(false); byte[] metaDataBuffer = ProtocolBufferSerializer.SerializedMaterial(serializedMaterial); resource.Serialize(this.referenceID, MetaDataType.PROTOBUF, metaDataBuffer, null); serializedAssets.AddResource(referenceID, PCFResourceType.MATERIAL, resource); //Nodes store their resource when serializing componentNode.SetSerializer(this); //Make sure caller can get the actual material referenceID when serializing its metadata. this.pointedID = this.referenceID; } #endif }