using System; using System.Collections.Generic; using UnityEngine; namespace Thousandto.Launcher.ExternalLibs { /// /// 可序列化的材质的信息 /// [Serializable] public class MaterialAssetData { //Shader的名字 public string ShaderName; //纹理列表 public MaterialPropertyTexture[] TextureArray; //纹理的偏移 public Vector2[] TextureOffsetArray; //纹理的缩放信息--tile public Vector2[] TextureScaleArray; //四元值列表 public MaterialPropertyVector[] VectorArray; //颜色列表 public MaterialPropertyColor[] ColorArray; //浮点值列表 public MaterialPropertyFloat[] FloatArray; #region//运行时执行 //临时保存的材质信息 --运行时 [NonSerialized] private Material _tempMaterial; //纹理加载的剩余数量 [NonSerialized] private int _tempTextureRemainCount = 0; //材质加载成功 [NonSerialized] private bool _isMaterialLoadFinished = true; //卸载资源 public void Unload() { //设置纹理 if (TextureArray != null) { bool hasTexPath = false; for (int i = 0; i < TextureArray.Length; i++) { var mt = TextureArray[i]; if (mt.Value != null) { Resources.UnloadAsset(TextureArray[i].Value); } if (mt.TexPath != null) { hasTexPath = true; } } if (hasTexPath) { PrefabAssetRuntimeUtil.ResetMateiralTexture(_tempMaterial); } } if (_tempMaterial != null) { GameObject.Destroy(_tempMaterial); } } //获取材质信息 public Material ToMaterialAsset() { if (_tempMaterial == null) { Shader sh = PrefabAssetRuntimeUtil.FindShader(ShaderName); if (sh == null) { Debug.LogError("ToMaterialAsset:not find shader;;" + ShaderName); return null; } _tempMaterial = new Material(sh); } if (_tempMaterial != null) { //设置纹理 if (TextureArray != null) { _isMaterialLoadFinished = false; _tempTextureRemainCount = TextureArray.Length; for (int i = 0; i < TextureArray.Length; i++) { var mt = TextureArray[i]; if (mt.Value != null) { _tempMaterial.SetTexture(mt.Name, mt.Value); _tempTextureRemainCount--; } else { if (string.IsNullOrEmpty(mt.TexPath)) { _tempMaterial.SetTexture(mt.Name, null); _tempTextureRemainCount--; } else { PrefabAssetRuntimeUtil.SetTexture(_tempMaterial, mt.Name, mt.TexPath, OnMaterialTextureCallBack); } } _tempMaterial.SetTextureOffset(mt.Name, TextureOffsetArray[i]); _tempMaterial.SetTextureScale(mt.Name, TextureScaleArray[i]); } if (_tempTextureRemainCount == 0) { if (!_isMaterialLoadFinished) { _isMaterialLoadFinished = true; } } } //设置四元值 if (VectorArray != null) { for (int i = 0; i < VectorArray.Length; i++) { _tempMaterial.SetVector(VectorArray[i].Name, VectorArray[i].Value); } } //设置颜色 if (ColorArray != null) { for (int i = 0; i < ColorArray.Length; i++) { _tempMaterial.SetColor(ColorArray[i].Name, ColorArray[i].Value); } } //设置float值 if (FloatArray != null) { for (int i = 0; i < FloatArray.Length; i++) { _tempMaterial.SetFloat(FloatArray[i].Name, FloatArray[i].Value); } } } return _tempMaterial; } //材质的纹理回调处理 private void OnMaterialTextureCallBack(Material mat, string pName) { _tempTextureRemainCount--; if (_tempTextureRemainCount == 0) { if (!_isMaterialLoadFinished) { _isMaterialLoadFinished = true; } } } #endregion #region//编辑器时执行--打包之前数据准备用 #if UNITY_EDITOR //设置材质--这里用于编辑器 public void FormMaterialAsset(Material mat,bool isUseTexName,string texDir) { //从Material中读取信息 var sh = mat.shader; string newShaderName; if (!CheckShader(sh.name, out newShaderName)) {//如果不是标准的Shader,那么就直接替换为一个默认shader sh = Shader.Find(newShaderName); } var cnt = PrefabAssetEditorUtil.GetShaderPropertyCount(sh); List texList = new List(); List offsetList = new List(); List scaleList = new List(); List vertorList = new List(); List colorList = new List(); List floatList = new List(); for (int i = 0; i < cnt; i++) { var type = (UnityEditor.ShaderUtil.ShaderPropertyType)PrefabAssetEditorUtil.GetShaderPropertyType(sh,i); var name = PrefabAssetEditorUtil.GetShaderPropertyName(sh, i); switch (type) { case UnityEditor.ShaderUtil.ShaderPropertyType.TexEnv: var tex = mat.GetTexture(name); var offset = mat.GetTextureOffset(name); var scale = mat.GetTextureScale(name); var mt = new MaterialPropertyTexture() { Name = name}; if (tex != null) { var path = UnityEditor.AssetDatabase.GetAssetPath(tex); if (path != null) { if (path.IndexOf(ConstDefines.CN_RAW_VFX_TEXTURE_DIR) >= 0) { mt.TexPath = texDir + tex.name; } else { var idx = path.IndexOf(ConstDefines.CN_TEXTURE_DIR); if (idx >= 0) { var sub = path.Substring(idx).Replace(ConstDefines.CN_TEXTURE_DIR, ""); idx = sub.IndexOf("/"); if (idx > 0) { sub = sub.Substring(0, idx); } //一个特殊路径:"类型:纹理名字" mt.TexPath = sub + ":" + tex.name; } else { mt.Value = tex; } } } else { mt.Value = tex; } } else { mt.Value = tex; } texList.Add(mt); offsetList.Add(offset); scaleList.Add(scale); break; case UnityEditor.ShaderUtil.ShaderPropertyType.Vector: var vect = mat.GetVector(name); vertorList.Add(new MaterialPropertyVector() { Name = name, Value = vect }); break; case UnityEditor.ShaderUtil.ShaderPropertyType.Color: var color = mat.GetColor(name); colorList.Add(new MaterialPropertyColor() { Name = name,Value = color }); break; default: var f = mat.GetFloat(name); floatList.Add(new MaterialPropertyFloat() { Name = name, Value = f }); break; } } //设置序列化的值 ShaderName = sh.name; TextureArray = texList.ToArray(); TextureOffsetArray = offsetList.ToArray(); TextureScaleArray = scaleList.ToArray(); VectorArray = vertorList.ToArray(); ColorArray = colorList.ToArray(); FloatArray = floatList.ToArray(); } //检验Shader的处理 private bool CheckShader(string shaderName,out string newShaderName) { newShaderName = shaderName; if (shaderName.StartsWith("Ares/") || shaderName.StartsWith("Gonbest/")) return true; newShaderName = "Gonbest/FallBack/FBWithMainTex"; return false; } #endif #endregion } }