unity导出的FBX引用default_mat的问题

来源:互联网 发布:ipad淘宝不能横屏新版 编辑:程序博客网 时间:2024/06/06 18:06

原文地址:http://www.jianshu.com/p/cc0410e0c31c

自己也遇到了这个问题,记录一下。。

0. 写在之前

本来创业之后,博客都计划整理成分量比较足、沉淀比较够的内容来做,但在游戏开发过程中,也不断踩了Unity的很多小坑。它们不足以整理成条理清晰、内容丰富的博客文章,但是填坑过程又花费了半天到一天的时间,如果记录下来给猜到同样坑的同学,也许就可以省去那么一些时间,于是决定新开一个小的笔记系列——Unity填坑笔记,我简单记录,您快速查看。

1. 起因

目前在做大世界的动态加载,加载的时候有明显的顿卡,于是通过Profile来查顿卡的原因,发现有Shader.Parse的调用,占用时间非常高,中低配机器上大约200ms+。
于是做了Shader的预编译,提前WarmUp用到的Shader,再次打包测试,依然有Shader.Parse的调用,通过Sample内存的差异来看编译了哪些Shader,其中有一大部分是Standard。


内存中有Standard的Shader

2. 原因

通过Profile右侧的Referenced By,可以查看当前的Asset被哪个东西引用,看了一下发现,都是被FBX引用了,导入的FBX文件中,都使用了Default-Material,而这个Default-Material是使用的Standard Shader。


FBX使用的Default-Material

3. 解决方法

这个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都被干掉了。


验证所有model都变粉了~

原创粉丝点击