人物基本模型,在group2下包含基本节点
装备模型
,在group2下包含所需装备
基本换装思路就是:根据所需装备将 将装备模型
group2下的SkinnedMeshRenderer复制到人物模型中
//获取主人物模型 void InstantiateSkeleton() { targetobj = Instantiate(Resources.Load("Play")) as GameObject; target = targetobj.transform; } //获取装备模型 void InstantiateAvatar() { sourceobj = Instantiate(Resources.Load("Zhuangbei")) as GameObject; source = sourceobj.transform; sourceobj.SetActive(false); }
找到装备模型中的包含的SkinnedMeshRenderer保存下来,并在人物模型中生成对应节点
void LoadAvatarData(Transform source) { if (source == null) return; SkinnedMeshRenderer[] parts = source.GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer part in parts) { string[] partName = part.name.Split('-'); if (!data.ContainsKey(partName[0])) { data.Add(partName[0], new Dictionary<string, Transform>()); GameObject partObj = new GameObject(); partObj.name = partName[0]; partObj.transform.parent = target.Find("group2"); targetSmr.Add(partName[0], partObj.AddComponent<SkinnedMeshRenderer>()); } data[partName[0]].Add(partName[1], part.transform); } }
根据选择的装备 将对应的
SkinnedMeshRenderer复制到人物模型中
对应节点中
void ChangePart(string part, string item) { //从资料中取得各部位指定编号的 SkinnedMeshRenderer SkinnedMeshRenderer smr = data[part][item].GetComponent<SkinnedMeshRenderer>(); //取得相对应名称的骨架物件来建立新的骨架列表 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; } } // 更新指定部位 GameObject 的 SkinnedMeshRenderer 内容 targetSmr[part].sharedMesh = smr.sharedMesh; targetSmr[part].bones = bones.ToArray(); targetSmr[part].materials = smr.materials; //一般到上面就可以了,但我那模型不知道是不是我改节点弄坏了, foreach (Transform hip in hips) { if (hip.name != smr.rootBone.name) continue; targetSmr[part].rootBone = hip; break; } }
具体代码:
using UnityEngine; using System.Collections.Generic; public class Dressing : MonoBehaviour { private Transform source; private Transform target; private GameObject sourceobj; private GameObject targetobj; private Dictionary<string, Dictionary<string, Transform>> data = new Dictionary<string, Dictionary<string, Transform>>(); private Transform[] hips; private Dictionary<string, SkinnedMeshRenderer> targetSmr = new Dictionary<string, SkinnedMeshRenderer>(); public static Dressing instance; // Use this for initialization void Start() { instance = this; InstantiateSkeleton(); InstantiateAvatar(); LoadAvatarData(source); hips = target.GetComponentsInChildren<Transform>(); } // Update is called once per frame void Update() { } //获取主人物模型 void InstantiateSkeleton() { targetobj = Instantiate(Resources.Load("Play")) as GameObject; target = targetobj.transform; } //获取装备模型 void InstantiateAvatar() { sourceobj = Instantiate(Resources.Load("Zhuangbei")) as GameObject; source = sourceobj.transform; sourceobj.SetActive(false); } //找到SkinnedMeshRenderer节点保存,并再play下生成新节点 void LoadAvatarData(Transform source) { if (source == null) return; SkinnedMeshRenderer[] parts = source.GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer part in parts) { string[] partName = part.name.Split('-'); if (!data.ContainsKey(partName[0])) { data.Add(partName[0], new Dictionary<string, Transform>()); GameObject partObj = new GameObject(); partObj.name = partName[0]; partObj.transform.parent = target.Find("group2"); targetSmr.Add(partName[0], partObj.AddComponent<SkinnedMeshRenderer>()); } data[partName[0]].Add(partName[1], part.transform); } } //将选择的节点的bones sharedMesh materials复制过去 void ChangePart(string part, string item) { //从资料中取得各部位指定编号的 SkinnedMeshRenderer SkinnedMeshRenderer smr = data[part][item].GetComponent<SkinnedMeshRenderer>(); //取得相对应名称的骨架物件来建立新的骨架列表 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; } } // 更新指定部位 GameObject 的 SkinnedMeshRenderer 内容 targetSmr[part].sharedMesh = smr.sharedMesh; targetSmr[part].bones = bones.ToArray(); targetSmr[part].materials = smr.materials; //一般到上面就可以了,但我那模型不知道是不是我改节点弄坏了, foreach (Transform hip in hips) { if (hip.name != smr.rootBone.name) continue; targetSmr[part].rootBone = hip; break; } } public string zuojian = "zuojian"; public string youjian = "youjian"; public string toukui = "toukui"; public string wuqi = "wuqi"; //GUI只为测试,没其他大用 void OnGUI() { if (GUILayout.Button("左肩铠甲")) { int mag = Random.Range(1, 3); ChangePart(zuojian, mag.ToString()); } else if (GUILayout.Button("右肩铠甲")) { int mag = Random.Range(1, 3); ChangePart(youjian, mag.ToString()); } else if (GUILayout.Button("头盔")) { int mag = Random.Range(1, 3); ChangePart(toukui, mag.ToString()); } else if (GUILayout.Button("武器")) { int mag = Random.Range(1, 3); ChangePart(wuqi, mag.ToString()); } } }
demo:
https://download.csdn.net/download/weixin_41843959/10419103