资源准备
1.每一套装备模型必须使用同一套骨骼,并单独将骨骼数据保存成一个Prefab。红色部分为武器挂节点(也可以把武器做成一个SkinnedMesh,不采用挂接点的形式),骨骼数据在Unity中的展示形式就是Transform。
2.将模型拆分成多个部分,将每一个部分单独保存成Prefab,武器也单独保存为一个Prefab。
每一个Prefab都含有自身的SkinnedMeshRenderer。
实现过程
1.创建骨骼GameObject,所有装备的蒙皮数据会最终合成到这个Prefab中。
2.创建装备GameObject,用于搜集其中蒙皮数据以生成新的SkinnedMeshRenderer到骨骼Prefab中。
3.public void CombineObject(GameObject skeleton, SkinnedMeshRenderer[] meshes,
bool combine = false)传入骨骼的GameObject和蒙皮数据。
4.搜集装备蒙皮数据中的有效信息。
1 | // Collect information from meshes |
5.为骨骼GameObject生成新的SkinnedMeshRenderer。
1 | // Create a new SkinnedMeshRenderer |
6.挂接武器。
1 | Transform[] transforms = Instance.GetComponentsInChildren<Transform(); |
其中WeaponInstance为武器实例GameObject,Instance为骨骼实例GameObject。
合成后的效果
如何优化
合成之后的模型拥有4个独立材质,加上独立的对象武器,也就是会产生5个Draw Call;如果将在骨骼中的这4个材质合并成一个,那么就能将Draw
Call减少到2个。
其中实现过程如下:
优化CombineObject方法,其中Combine为bool类型,用于标识是否合并材质。
1 | // merge materials |
生成新的SkinnedMeshRenderer时略有区别:
最终效果如下:
可以看出,新的SkinnedMeshRenderer只有一个材质,Draw Call自然也就降低了。
示例工程
GitHub:https://github.com/zouchunyi/UnityAvater
感兴趣的朋友可以下载。工程中代码大家可以直接使用,但是美术资源不得用于任何商业用途。