284 lines
11 KiB
C#
Raw Permalink Normal View History

2025-01-25 04:38:09 +08:00
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Thousandto.Launcher.ExternalLibs
{
/// <summary>
/// 可序列化的材质的信息
/// </summary>
[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<MaterialPropertyTexture> texList = new List<MaterialPropertyTexture>();
List<Vector2> offsetList = new List<Vector2>();
List<Vector2> scaleList = new List<Vector2>();
List<MaterialPropertyVector> vertorList = new List<MaterialPropertyVector>();
List<MaterialPropertyColor> colorList = new List<MaterialPropertyColor>();
List<MaterialPropertyFloat> floatList = new List<MaterialPropertyFloat>();
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
}
}