一个模型 带有skinnedMeshRender组件 的子节点 和对应坐标信息的骨骼绑定的子节点
初始化的时候给玩家添加skinnedMeshRender组件
骨骼和子节点的预制体
把身体的部位分成三份 1头部 2 衣服 3腿部 然后用数组对象管理起来
bodys[0] = Resources.Load<GameObject>("MyPlayer/tou" + touid);
bodys[1] = Resources.Load<GameObject>("MyPlayer/yifu" + yifuid);
bodys[2] = Resources.Load<GameObject>("MyPlayer/tui" + tuiid);
三个部位先加载出来
后面就是找到当前的骨骼及名称去对应的部位中找到需要使用的骨骼合并网格材质球
public GameObject[] bodys;
public int touid = 1;
public int yifuid = 1;
public int tuiid = 1;
bodys[0] = Resources.Load<GameObject>("MyPlayer/tou" + touid);
bodys[1] = Resources.Load<GameObject>("MyPlayer/yifu" + yifuid);
bodys[2] = Resources.Load<GameObject>("MyPlayer/tui" + tuiid);
//1.找到当前所有骨骼及名称
Transform[] allaones = GetComponentsInChildren<Transform>();
Dictionary<string, Transform> dicbones = new Dictionary<string, Transform>();
//2.把所有骨骼以名称作为key存入字典,方便后面查找
for (int i = 0; i < allaones.Length; i++)
{
dicbones.Add(allaones[i].name, allaones[i]);
}
//3.去每个对应部位中找到需要使用的骨骼,并将其保存
List<Transform> bones = new List<Transform>();
//合并网格材质球
List<CombineInstance> combines = new List<CombineInstance>();
List<Material> materials = new List<Material>();
for (int i = 0; i < bodys.Length; i++)
{
//找网格
CombineInstance combin = new CombineInstance();
combin.mesh = bodys[i].GetComponentInChildren<SkinnedMeshRenderer>().sharedMesh;
combin.transform = bodys[i].transform.localToWorldMatrix;
combines.Add(combin);
//找材质球
materials.Add(bodys[i].GetComponentInChildren<SkinnedMeshRenderer>().sharedMaterial);
//找骨骼
Transform[] bodybones = bodys[i].GetComponentInChildren<SkinnedMeshRenderer>().bones;
for (int j = 0; j < bodybones.Length; j++)
{
//注意:我要使用的是自己的骨骼,而不是预制体上的骨骼
bones.Add(dicbones[bodybones[j].name]);
}
}
Mesh mesh = new Mesh();
mesh.CombineMeshes(combines.ToArray(), false,false);
GetComponent<SkinnedMeshRenderer>().sharedMesh = mesh;
GetComponent<SkinnedMeshRenderer>().materials = materials.ToArray();
GetComponent<SkinnedMeshRenderer>().bones = bones.ToArray();
轮转图脚本
public CombinPlayer combin;
public Transform player;
public Image prefab;
public float spacing = 100;
public float max = 1;
public float min = 0.5f;
public int num = 5;
float c;
float r;
float ang;
float dis = 0;
float cutspeed = 100;
List<GameObject> list = new List<GameObject>();
List<Transform> sorts = new List<Transform>();
// Start is called before the first frame update
void Start()
{
c = (prefab.rectTransform.rect.width + spacing) * num;
r = c / (2 * Mathf.PI);
ang = (2 * Mathf.PI) / num;
player.transform.localScale = new Vector3(0,0, (max - min) * 0.5f + min) ;
sorts.Add(player);
Move();
}
public void Move()
{
float moveang = dis / r;
for (int i = 0; i < num; i++)
{
float x = Mathf.Sin(i * ang + moveang) * r;
float z = Mathf.Cos(i * ang + moveang) * r;
float p=(z+r)/(r+r);
float scale = (max - min) * p + min;
if(list.Count<=i)
{
GameObject image = Instantiate(prefab.gameObject, transform);
image.GetComponent<Image>().sprite= Resources.Load<Sprite>("Image/image_" + i);
int n = i;
image.GetComponent<Button>().onClick.AddListener(() =>
{
switch(n / 2)
{
case 0:combin.touid = n % 2;break;
case 2:combin.yifuid = n % 2;break;
case 1:combin.tuiid= n % 2;break;
}
combin.ChangeOfOutfit();
});
list.Add(image);
sorts.Add(image.transform);
}
list[i].transform.localPosition = new Vector3(x, p*-100, 0);
list[i].transform.localScale = Vector3.one * scale;
}
sorts.Sort((a, b) =>
{
if(a.localScale.z<b.localScale.z)
{
return -1;
}
else if (a.localScale.z == b.localScale.z)
{
return 0;
}
else
{
return 1;
}
});
for (int i = 0; i < sorts.Count; i++)
{
sorts[i].SetSiblingIndex(i);
}
}
public void OnDrag(PointerEventData eventData)
{
dis += eventData.delta.x;
Move();
}