Unity SkinnedMeshRenderer 动态换装系统

说在前面

本文只是实例说明了最基础的换装思路:刷新骨骼
完整的换装系统需要涉及到:Mesh合并、刷新骨骼、材质合并

直接上效果
在这里插入图片描述
动态换装需要了解SkinnedMeshRenderer动画如何播放。
本质上是骨骼的运动,拖拽着Mesh的定点进行运动(一个定点会被多个骨骼按权重控制),以此形成动画。
骨骼在SkinnedMeshRenderer中是字段bones,是一个Transform[],一般在模型中可以看到skeleton节点下密密麻麻的骨骼,如下图
在这里插入图片描述

简单来说动态换装其实就是给衣服部件动态的替换骨骼,需要做的有两步:

  1. 收集骨骼(就是一堆TransForm)
  2. 将部件的骨骼挨个刷新
    代码如下:

第一步
可以从Skeleton为根节点通过GetComponentsInChildren<Transform>()方式获取根节点下骨骼。
在实例中,我的这个模型中,根节点包含了头部(头部部件不是SkinnedMeshRenderer),比较特殊,所以从body(身子部分)的Mesh中获取骨骼,效果是一样的。

bonesDic = new Dictionary<string, Transform>();
SkinnedMeshRenderer bodySMR = transform.Find("body").GetComponent<SkinnedMeshRenderer>();
for (int i = 0; i < bodySMR.bones.Length; i++)
{
    
    
    string boneName = bodySMR.bones[i].name;
    Transform bone = bodySMR.bones[i];
    if (!bonesDic.ContainsKey(boneName))
    {
    
    
        bonesDic.Add(boneName, bone);
    }
}

第二步
将身体部件的骨骼替换成收集好的骨骼
因为部件只会涉及到部分骨骼,所以按照原有的骨骼名进行全部替换
其中partObj就是要换装的部分

SkinnedMeshRenderer smr = partObj.GetComponent<SkinnedMeshRenderer>();
List<Transform> bones = new List<Transform>();
for (int i = 0; i < smr.bones.Length; i++)
{
    
    
    string name = smr.bones[i].name;
    if (bonesDic.ContainsKey(name))
    {
    
    
        bones.Add(bonesDic[name]);
    }
}
smr.bones = bones.ToArray();

以上就是动态换装的思路
总的来说,以上方式实现换装很简单,可以实现效果,但是一般在工程中同时要考虑效率。这就涉及到mesh合并以及材质合并,这部分才是换装新系统的重要部分。

猜你喜欢

转载自blog.csdn.net/YuAnHandSome/article/details/128241355