Unity 结合轮转图和SkinnedMeshRenderer(蒙皮网格渲染)初步制作换装系统

在粘贴和打字之前不妨多想想,这么一个东西都需要些什么来组成
在这里插入图片描述

1 构成换装的轮转图
2 带有骨骼和 SkinnedMeshRenderer 的初始模型
3 让轮转图的索引与部件对应后加载的方法

轮转图在之前已经解释,只需要在原有的基础上增加 一个标识图片对其后的索引属性

……
public string ClothID;
……
拖拽对齐图片后将获取图片索引赋值
 ClothID = path+list.IndexOf(trans[num - 1].GetComponent<Image>());

这样就完成了第一部分,获取到哪一个预制体的索引

第二步需要准备一个带骨骼的模型,美术部分应该交给专业的来。
拥有了这两步,剩下的就是简单的拼装了

拼装的指令由UI上的Button发出,并需要获取当前对齐图片的 Id索引,

List<GameObject> bodys = new List<GameObject>();
        for (int i = 0; i < rc.Length; i++)
        {
    
    
            bodys.Add(Resources.Load<GameObject>("PlayerPro/Prefabs/" + pic[i].ClothID));
        }.
        //前面的循环是按照索引实例化对应的组件
        //下面则是用于 SkinnedMeshRenderer组件数值设置
        Replace(bodys.ToArray(), CombinePlayer.player);

Replace的设置如下

public static void Replace(GameObject[] bodys, GameObject avatar)
    {
    
    
        //网格合并
        Mesh mesh = new Mesh();
        List<CombineInstance> combines = new List<CombineInstance>();
        for (int i = 0; i < bodys.Length; i++)
        {
    
    
            CombineInstance combine = new CombineInstance();
            combine.mesh = bodys[i].GetComponentInChildren<SkinnedMeshRenderer>().sharedMesh;
            combines.Add(combine);
        }
        mesh.CombineMeshes(combines.ToArray(), false, false);
        avatar.GetComponent<SkinnedMeshRenderer>().sharedMesh = mesh;

        //上材质
        List<Material> materials = new List<Material>();
        for (int i = 0; i < bodys.Length; i++)
        {
    
    
            // sharedMaterial 是材质球本体
            materials.Add(bodys[i].GetComponentInChildren<SkinnedMeshRenderer>().sharedMaterial);
        }
        avatar.GetComponent<SkinnedMeshRenderer>().materials = materials.ToArray();

        //骨骼
        获取
        Transform[] allBones = avatar.GetComponentsInChildren<Transform>();
        //字典以骨骼名为键,骨骼Transform作值
        Dictionary<string, Transform> dicBones = new Dictionary<string, Transform>();
        foreach (Transform bone in allBones)
        {
    
    
            //print(bone.name);
            dicBones.Add(bone.name, bone);
        }

        List<Transform> myBones = new List<Transform>();
        //外层循环角色模型
        for (int i = 0; i < bodys.Length; i++)
        {
    
    
            //内层获取角色模型上的 SkinnedMeshRenderer 组件
            Transform[] bodyBones = bodys[i].GetComponentInChildren<SkinnedMeshRenderer>().bones;
            for (int j = 0; j < bodyBones.Length; j++)
            {
    
    
                //检测是否与字典内键匹配
                
                if (dicBones.ContainsKey(bodyBones[j].name))
                {
    
    
                    
                    //成功为需要的骨骼,添加进myBones
                    myBones.Add(dicBones[bodyBones[j].name]);
                    print(myBones[j].name);
                }
            }
        }
        //获取模型上的SkinnedMeshRenderer,将myBones里筛选过的赋值,更新
        avatar.GetComponent<SkinnedMeshRenderer>().bones = myBones.ToArray();

    }

注意的点是,网格、材质、骨骼缺一不可,虽然理论上骨骼只是用于模型动态上,缺失也只会造成静态模型,实际则会出现模型消失的情况,暂无优解

关于预制体图片的生成在
这一期也有相应的代码方法而2D轮转图
部分在这也有解释,只需要添加上文的属性与对齐方法。

完结如下

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_57252175/article/details/132400044