uinty SkinnedMeshRenderer 實現換裝系統 (更換模型節點)
阿新 • • 發佈:2019-02-02
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()); } } }