0. 写在之前
本来创业之后,博客都计划整理成分量比较足、沉淀比较够的内容来做,但在游戏开发过程中,也不断踩了Unity的很多小坑。它们不足以整理成条理清晰、内容丰富的博客文章,但是填坑过程又花费了半天到一天的时间,如果记录下来给猜到同样坑的同学,也许就可以省去那么一些时间,于是决定新开一个小的笔记系列——Unity填坑笔记,我简单记录,您快速查看。
1. 起因
目前在做大世界的动态加载,加载的时候有明显的顿卡,于是通过Profile来查顿卡的原因,发现有Shader.Parse的调用,占用时间非常高,中低配机器上大约200ms+。
于是做了Shader的预编译,提前WarmUp用到的Shader,再次打包测试,依然有Shader.Parse的调用,通过Sample内存的差异来看编译了哪些Shader,其中有一大部分是Standard。
2. 原因
通过Profile右侧的Referenced By,可以查看当前的Asset被哪个东西引用,看了一下发现,都是被FBX引用了,导入的FBX文件中,都使用了Default-Material,而这个Default-Material是使用的Standard Shader。
FBX使用的Default-Material3. 解决方法
这个Default-Material并不能被修改,于是我搜索了半天,找到一个插件号称可以支持替换Default-Material,够买来看了下,用的是在AssetPostprocessor中OnAssignMaterialModel来替换材质的方法,实例代码供参考:
protected virtual Material OnAssignMaterialModel(Material previousMaterial, Renderer renderer)
{
var materialPath = "Assets/Default_Materiall.mat";
if (AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)))
{
return AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)) as Material;
}
Debug.Log(previousMaterial.name);
return previousMaterial;
}
这样只需要提供一个自定义的Default_Material.mat文件,重新导入所有的FBX文件,就可以进行替换了。
另外一个种方法是UWA群里的朋友提供了,就是删除掉Defualt-Material,沿着这个思路搜索了一下,发现网上已经有解决方案:删除FBX的默认材质
示例代码如下:
/// <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];
}
}
}
注意这里不能将sharedMaterials设置为null,而是要new一个空的列表给它。
给一个遍历代码来处理所有的FBX文件:
// 添加重新导入fbx的功能。
[MenuItem("Assets/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);
}
}
}
4. 坑
除了前面提到的Default-Material会导致按照AB打包可能重复加载Standard Shader,Unity 5.5.1f版本还有一个坑就是如果用了Remote的Cache Server,会导致AssetDatabase.ImportAsset不会更新内容,因为这个问题坑了我很久。。。因为右键直接ReImport是可以更新的,但是如果想Reimport All,会重新导入贴图,时间占用非常多,因此一直想只处理fbx文件,但是在Unity 5.5.1f版本中一直不太对,后来查到这个bug Report
可恨的是,我本地貌似调用前面写的ReimportAllFBX方法会把Cache Server设置为Remote!虽然不能理解,但是现象貌似就是如此。。。
最后,升级了Unity版本到5.5.3f,依然关闭Cache Server,重新导入所有的,可以了。
tips:可以通过Project中只显示model来过滤查看所有的模型是否都是粉色的来保证所有的Default-Material都被干掉了。
网友评论