unity 角色換裝


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;//更換材質
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM