前言:
前文讲到虽然实现了纹理换装,且极大降低美术工作量,但是有个致命缺点,胡乱搭配会极大地损坏极度风格化的闹闹整体画面。但是如果整体替换某一部分,那么损坏程度将大大降低,且效果也要比纹理换装大大增强,因为他能够改变模型本身,虽然也有一定的制约性(后面会提到)。这有很多优点,唯一的缺点就是美术工作点大,特别是前文提到的,我们的模型已经做好,需要重新拆分和蒙皮,甚至可能会换骨骼,换骨骼又会导致换动作,相当于先前的美术工作都得重来。但是如果后续模型按照这个要求来做的话,工作量就不会增加很多。唉,又要马儿跑得快,又要马儿不吃草是不可能的啊。
思路:
SkinMesh在Unity和其他引擎差不太多,无非不了就是Mesh的顶点受Bone的控制,弄清楚接口,设置进去,就不会出问题,对于Unity就是设置这几个参数sharedMesh,meterials,bones,rootBone。这四个参数设置正确就能正确显示。前两个参数就是显示相关,比较简单直接设置成我们需要替换部件的Mesh和材质。后面的Bones和RootBone,由于是将新的部件嫁接到原模型上,所以要求把Bones和RootBone通过新部件的配置文件找到对应在原模型的骨骼Transform上。
原理好像很简单,但是这里边有很多坑,或者说限制。因为需要把新的Bones跟原模型Boes对应上,所以要求就是新部件的骨骼必须要能和原模型的骨骼严格对应上。经测试发现,新部件的骨骼可以比原骨骼少,多了是显然不行的,因为你都找不到对应的骨骼。最好就是在制作新皮肤部件时,就用原骨骼来蒙皮。这个限制其实挺致命的,因为新骨骼只能少不能多,那在制作原骨骼的时候,就得考虑后面出皮肤新部件的需求。还有一点就是骨骼的命名必须特别规范,不然在找对应骨骼时会出问题。
实现:
这个原理,比较简单,但是在需找对应的过程是很繁琐的。实现方式应该有很多种,总之最后能把骨骼对应上就OK。
配置文件
public class LKSkinnedMeshRendererData : ScriptableObject
{
public Material[] materials;
public Mesh mesh;
public string[] boneNames;
public int[] subMeshIndices;
public string rootName;
}
这些,如果让美术填的话显然不现实,得弄一个自动生成配置文件的脚本。这些,如果让美术填的话显然不现实,得弄一个自动生成配置文件的脚本。
private const string assetExtension = ".asset";
private const string prefabExtension = ".prefab";
private const string modelAssetFolderName = "ModelAssets";
[MenuItem("LK-TOOL/AssetGe