首先,将所有需要替换的部位预制体添加组件SkinnedMeshRenderer ,再为角色创建新的网格和合并网格集合,获取所有换装部位的sharedMesh存入合并网格集合,再将所有合并网格信息转为数组存入新创建的人物网格信息中。
再获取所有替换部位的组件材质,并存入材质集合中,最后转成数组存入人物SkinnedMeshRenderer的材质数组中。
最后获取人物自身的所有骨骼信息存入字典中,再将需要替换的部位的骨骼信息存入集合中,循环集合中的骨骼信息判断是否与人物的骨骼信息一致,将所有相同信息的骨骼存入集合,再将集合存入到SkinnedMeshRenderer组件的骨骼信息中,运行实现效果,代码如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Changebodys : MonoBehaviour
{
public GameObject[] bodys;
// Start is called before the first frame update
private void Start()
{
Chnage();
}
public void Chnage()
{
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;
//combine.transform = bodys[i].GetComponentInChildren<SkinnedMeshRenderer>().worldToLocalMatrix;
combines.Add(combine);
}
mesh.CombineMeshes(combines.ToArray(), false, false);
GetComponent<SkinnedMeshRenderer>().sharedMesh = mesh;
List<Material> materials = new List<Material>();
for (int i = 0; i < bodys.Length; i++)
{
materials.Add(bodys[i].GetComponentInChildren<SkinnedMeshRenderer>().sharedMaterial);
}
GetComponent<SkinnedMeshRenderer>().materials = materials.ToArray();
Transform[] allbones = GetComponentsInChildren<Transform>();
Dictionary<string, Transform> dic = new Dictionary<string, Transform>();
foreach (var item in allbones)
{
dic.Add(item.name, item);
}
List<Transform> mybones = new List<Transform>();
for (int i = 0; i < bodys.Length; i++)
{
Transform[] bones = bodys[i].GetComponentInChildren<SkinnedMeshRenderer>().bones;
for (int j = 0; j < bones.Length; j++)
{
if (dic.ContainsKey(bones[j].name))
{
mybones.Add(dic[bones[j].name]);
}
}
}
GetComponent<SkinnedMeshRenderer>().bones = mybones.ToArray();
}
}
再结合2D轮转图实现换装效果