unity角色换装的关键是更改角色部位上的物体的SkinnedMeshRenderer组件的属性:
更改mesh:mesh决定了部位的物体的外形,是主要的数据。
刷新骨骼:同一个部位下,不同的mesh受到的不同的骨骼的影响不同,因此更换mesh之后,还要更新SkinnedMeshRenderer下的骨骼列表的信息,也就是更换骨骼列表。
替换材质:一个SkinnedMeshRenderer下由多个材质作用,因此还需要更换材质列表。
操作过程为,从预制物体中获取的需要更换的相关部位的mesh,然后通过从预制物体的相关部位的SkinnedMeshRenderer下获取到影响该部位的骨骼列表,然后从场景角色的骨骼下获取到同名的骨骼列表,将该骨骼列表赋予到场景下角色的部位的SkinnedMeshRenderer下,并且获取到预制物体下该部位的材质列表,同样的将该列表赋予场景下角色的部位的SkinnedMeshRenderer下。
为了获取到更换的信息,需要由预制物体存储物体的相关信息。预制物体如下,每个部位下所有的物体都呈现,便于程序提取信息。
原模型如下:
场景下角色如下:
具体代码如下:
该脚本可以放在任何地方
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AvatarSysDemo00 : MonoBehaviour
{
public Transform role;//场景中的角色物体
public GameObject rolePrefab;//预制物体
public GameObject kuzi;//场景中角色物体下裤子物体
public string[] kuziNames;//所有的用于替换的裤子的名字,用于再预制物体中找到相关的物体的信息
public GameObject[] objs;//裤子相关的预制物体
int index = 0;//当前的装备索引
public Transform[] hips;//角色的骨骼物体
private void Awake()
{
hips = null;
if (role)
hips = role.GetComponentsInChildren<Transform>();//首先获取场景中角色下的骨骼列表
for (int i = 0; i < kuziNames.Length; i++)//获取预制物体下的所有裤子物体
{
Transform kuziObj = rolePrefab.transform.Find(kuziNames[i]);
objs[i] = kuziObj.gameObject;
}
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))//设置为按下空格就切换一下裤子
{
Debug.Log(objs.Length);
if (objs.Length == 0) return;
index = (index + 1) % objs.Length;
ChangeMesh(objs[index]);
}
}
//换装
public void ChangeMesh(GameObject part)
{
SkinnedMeshRenderer smr = part.GetComponent<SkinnedMeshRenderer>();//获取预制物体下相关部位的SkinnedMeshRenderer
//获取角色物体下与预制物体相关更换的Mesh部位下作用于该Mesh,再场景中与其同名的骨骼列表
List<Transform> bones = new List<Transform>();
foreach (Transform bone in smr.bones)
{
foreach (Transform hip in hips)
{
if (hip.name != bone.name)
{
continue;
}
bones.Add(hip);
break;
}
}
kuzi.GetComponent<SkinnedMeshRenderer>().sharedMesh = smr.sharedMesh;//更改mesh
kuzi.GetComponent<SkinnedMeshRenderer>().bones = bones.ToArray();//更换(刷新)骨骼列表
kuzi.GetComponent<SkinnedMeshRenderer>().materials = smr.sharedMaterials;//更换材质
}
}
来源:oschina
链接:https://my.oschina.net/u/4271371/blog/3456709