一.换装
1.受蒙皮影响的位置一般分为(头,身体,腿等),我们的换装主要是针对这几个部位进行动态更换
下面是主骨骼
主骨骼必须是带有SkinnedMeshRenderer这个组件
2.为主骨骼创建一个脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeMesh : MonoBehaviour
{
public GameObject[] bodys;//定义物体数组
public static ChangeMesh instance;
private void Awake()
{
instance = this;
}
// Start is called before the first frame update
void Start()
{
Change();
}
public void Change()//换装函数
{
//创建一个新的网格,把各个部件的网格合并到一个新的网格
Mesh mesh = new Mesh();
//网格合并实例集合
List<CombineInstance> combines = new List<CombineInstance>();
//材质的集合
List<Material> materials = new List<Material>();
//获取骨骼信息
Transform[] allbones=transform.GetComponentsInChildren<Transform>();
//骨骼信息定义一个字典
Dictionary<string,Transform> dicBones = new Dictionary<string,Transform>();
//骨骼信息添加到字典中
foreach (Transform t in allbones)
{
dicBones.Add(t.name, t);
}
//再次新建一个存储骨骼信息
List<Transform> mybones= new List<Transform>();
//遍历取出身体部件上的骨骼信息
for (int i=0;i< bodys.Length;i++)
{
//新建网格合并实例
CombineInstance combine = new CombineInstance();
//网格合并中的网格进行赋值
combine.mesh = bodys[i].GetComponentInChildren<SkinnedMeshRenderer>().sharedMesh;
//网格合并实例进行添加
combines.Add(combine);
//材质物体添加此物体上的共享材质
materials.Add(bodys[i].GetComponentInChildren<SkinnedMeshRenderer>().sharedMaterial);
//取出某个部件的骨骼信息
Transform[] bones = bodys[i].GetComponentInChildren<SkinnedMeshRenderer>().bones;
//遍历取出的骨骼信息
for (int j = 0; j < bones.Length; j++)
{
//如果自己的骨骼字典中有和其相同的骨骼
if (dicBones.ContainsKey(bones[i].name))
{
//新建的骨骼集合进行添加
mybones.Add(dicBones[bones[j].name]);
}
}
}
//将存储三件服装的网格合并实例集合
mesh.CombineMeshes(combines.ToArray(),false,false);
//新的网格信息赋值给自己
GetComponent<SkinnedMeshRenderer>().sharedMesh = mesh;
//共享材质信息赋值给自己
GetComponent<SkinnedMeshRenderer>().materials=materials.ToArray();
//最后再将新骨骼集合化为Object类型给自身骨骼赋值
GetComponent<SkinnedMeshRenderer>().bones=mybones.ToArray();
}
这是一些身体部件的预制体
写一个改变身体部位的方法
public void ChangeHuan(string name)
{
if(name.Contains("Tou"))
{
bodys[0] = Resources.Load<GameObject>("Prefabs/" + name);
bodys[1] = bodys[1];
bodys[2] = bodys[2];
Change();
return;
}
if(name.Contains("YiFu"))
{
bodys[0] = bodys[0];
bodys[1] = Resources.Load<GameObject>("Prefabs/" + name);
bodys[2] = bodys[2];
Change();
return;
}
if(name.Contains("Tui"))
{
bodys[0] = bodys[0];
bodys[1] = bodys[1];
bodys[2]= Resources.Load<GameObject>("Prefabs/" + name);
Change();
return;
}
}
在2d轮转图中调用这个方法
public void OnEndDrag(PointerEventData eventData)
{
float dis = eventData.delta.x;
float time = Mathf.Abs(dis / dec);
DOTween.To((a) =>
{
allang -= a / dec;
Move();
}, dis, 0, time).OnComplete(() =>
{
int index= objects.IndexOf(trans[trans.Count-1].GetComponent<Image>());
print("抽到了" + transform.name + index);
ChangeMesh.instance.ChangeHuan(transform.name + index);
float moveang = Mathf.Asin(trans[num-1].transform.localPosition.x/r);
float moveangtime = Mathf.Abs(moveang * r / dec);
DOTween.To((b) =>
{
allang = b;
Move();
},allang,allang+moveang,moveangtime);
});
}
效果如下: