关于Unity自动生成材质球的问题
程序员文章站
2022-06-10 20:58:49
...
1,发现问题
上周末发了一个版本,发现动态加载有明显的卡顿,于是通过Profile来查顿卡的原因,发现里面Shader.Parse的调用,占用时间非常高,进一步发现里面有不少默认的Standard材质,单纯一个默认材质就有4.8MB加载,每增加一个角色模型 就多加一个默认材质。 最可怕单个FBX它同时加载 默认材质 与我们项目自身的写的那个材质。
2,问题起因
MAX导出FBX会默认带一个材质球信息进去unity引擎,默认的命名为Default-Material 这个材质,最讨厌的一点它还是使用Standard材质!!
3,解决方法
做为美术的我开始找MAX导入插件里面 有没有剔除这个材质的方法,找了很久并没有发现这个选项,加上大量已经制作完成的角色模型 如果要全部重新导入修改太麻烦, 就开始直接想要用脚本一次性解决,替换成我想要的材质。
[MenuItem("Assets/更改模型材质")]
public static void ChangeModel()
{
Object[] objs = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
for (int i = 0; i < objs.Length; i++)
{
Object obj = objs[i];
string url = AssetDatabase.GetAssetPath(obj);
if (string.IsNullOrEmpty(url))
continue;
string ext = Path.GetExtension(url);
if (ext != ".fbx" && ext != ".FBX")
continue;
if (!ContainsPath(url))
continue;
ModelImporter modelImporter = ModelImporter.GetAtPath(url) as ModelImporter;
modelImporter.importMaterials = true;
modelImporter.materialLocation = ModelImporterMaterialLocation.External;
modelImporter.materialName = ModelImporterMaterialName.BasedOnTextureName;
modelImporter.materialSearch = ModelImporterMaterialSearch.Everywhere;
AssetDatabase.ImportAsset(url);
AssetDatabase.Refresh();
obj = AssetDatabase.LoadAssetAtPath<Object>(url);
GameObject go = obj as GameObject;
Renderer[] skins = go.GetComponentsInChildren<SkinnedMeshRenderer>(true);
if (skins.Length == 0)
{
skins = go.GetComponentsInChildren<MeshRenderer>(true);
}
if (skins.Length == 0)
return;
if (skins.Length > 1)
{
}
Renderer renderer = skins[0];
if (renderer.sharedMaterials != null && renderer.sharedMaterials.Length > 0)
{
for (int j = 0; j < renderer.sharedMaterials.Length; j++)
{
Material mat = renderer.sharedMaterials[j];
if (mat != null)
{
mat.shader = Shader.Find("Character/Character");
}
}
}
}
}
}
这是办法之一
解决办法之二
就是不让它在unity生成材质球,或者生成一个材质 全部模型公用,将消耗降到最小,或者删除默认材质
public class FbxTools : AssetPostprocessor
{
public static string DefaultMaterialPath = "Assets/Common/Materials/DefaultMaterial.mat";
// 添加重新导入fbx的功能。
[MenuItem("Assets/Fbx/Reimport all FBX")]
public static void ReimportAllFBX()
{
var files = AssetDatabase.GetAllAssetPaths();
foreach (var vv in files)
{
var vvLower = vv.ToLower();
if (vvLower.EndsWith("fbx"))
{
AssetDatabase.ImportAsset(vv, ImportAssetOptions.ImportRecursive | ImportAssetOptions.ForceUpdate);
}
}
}
//删除默认的材质球 方法
/// <summary>
/// 对于模型,删除共享材质,保证不会将包括Standard这样的材质打包到游戏中。
/// </summary>
/// <param name="model"></param>
//public void OnPostprocessModel(GameObject model)
//{
// Renderer[] renders = model.GetComponentsInChildren<Renderer>();
// if (null != renders)
// {
// foreach (Renderer render in renders)
// {
// render.sharedMaterials = new Material[render.sharedMaterials.Length];
// }
// }
//}
AssetPostprocessor
void OnPreprocessModel() { ModelImporter modelImporter = assetImporter as ModelImporter; modelImporter.importMaterials = false; } Material OnAssignMaterialModel(Material material, Renderer renderer) { Debug.Log("Invalid Material Name: " + material.name); Material defaultMaterial = AssetDatabase.LoadAssetAtPath<Material>(DefaultMaterialPath); if (defaultMaterial == null) { defaultMaterial = new Material(Shader.Find("Unlit/Texture")); AssetDatabase.CreateAsset(defaultMaterial, DefaultMaterialPath); } return defaultMaterial; }}上一篇: 冬天老年人皮肤瘙痒 四招即可轻松缓解
下一篇: 冬季养生小常识之老人如何过冬?
推荐阅读