1. 程式人生 > >uinty SkinnedMeshRenderer 實現換裝系統 (更換模型節點)

uinty SkinnedMeshRenderer 實現換裝系統 (更換模型節點)

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());
        }
    }

}