Unity游戏换装

原理:

 将一个模型拆分成多个skinmesh renderer,然后写一个脚本将它们分别赋值。最终通过零散的skinmesh最终组合成一个全新的

mesh,最终达到实现一个新的模型,达到换装的目的。参考代码如下:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

[RequireComponent(typeof(SkinnedMeshRenderer))]
public class TestChangeCloth : MonoBehaviour
{
    private enum GeneraterType
    {
        ALL,
        EYE,
        FACE,
        HAIR,
        PANT,
        SHOES,
        BODY
    }

    //可以供选择的对象列表  
    public List<GameObject> eyeList = new List<GameObject>();
    public List<GameObject> faceList = new List<GameObject>();
    public List<GameObject> hairList = new List<GameObject>();
    public List<GameObject> pantList = new List<GameObject>();
    public List<GameObject> shoesList = new List<GameObject>();
    public List<GameObject> bodyList = new List<GameObject>();
    public List<GameObject> handList = new List<GameObject>();

    //角色的SkinMeshRenderer组件上的材质列表  
    private List<Material> materialList = new List<Material>();
    //角色的SkinMeshRenderer组件上的骨骼列表  
    private List<Transform> boneList = new List<Transform>();
    //角色的子网格,对这些子网格进行拼接后形成角色的完整网格  
    private List<CombineInstance> ciList = new List<CombineInstance>();
    //角色的网格  
    private Mesh mesh;
    //角色的骨骼节点  
    private Transform[] allBones;
    //组件  
    private SkinnedMeshRenderer smr;
    // Use this for initialization  
    void Start()
    {
        //获取蒙皮组件  
        smr = this.GetComponent<SkinnedMeshRenderer>();
        //随机种子  
        Random.seed = (int)Time.time;
        //获取各个骨骼节点  
        allBones = this.GetComponentsInChildren<Transform>();

        //生成  
        GeneraterSkin(GeneraterType.ALL);
    }

    // Update is called once per frame  
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            GeneraterSkin(GeneraterType.ALL);
        }

    }

    private void Reset()
    {
        ciList.Clear();
        materialList.Clear();
        boneList.Clear();
    }

    /// <summary>  
    /// 生成蒙皮  
    /// </summary>  
    private void GeneraterSkin(GeneraterType type)
    {
        Reset();

        GetNextSkin(eyeList);
        GetNextSkin(faceList);
        GetNextSkin(hairList);
        GetNextSkin(pantList);
        GetNextSkin(shoesList);
        GetNextSkin(bodyList);
        GetNextSkin(handList);

        mesh = new Mesh();
        mesh.CombineMeshes(ciList.ToArray(), false, false);
        smr.sharedMesh = mesh;

        smr.materials = materialList.ToArray();

        smr.bones = boneList.ToArray();
    }

    /// <summary>  
    /// 随机获得蒙皮  
    /// </summary>  
    private void GetNextSkin(List<GameObject> list)
    {
        if (list.Count > 0)
        {
           // GameObject go = list[Random.Range(0, list.Count)];
            for(int i = 0; i < list.Count; i++)
            {
                GameObject go = list[i];

                SkinnedMeshRenderer goSMR = go.GetComponent<SkinnedMeshRenderer>();
                if (goSMR)
                {
                    for(int sub = 0; sub < goSMR.sharedMesh.subMeshCount; sub++)
                    {
                        CombineInstance ci = new CombineInstance();
                        ci.mesh = goSMR.sharedMesh;
                        ci.subMeshIndex = sub;
                        ciList.Add(ci);

                        materialList.Add(goSMR.sharedMaterials[sub]);
                        GetBone(goSMR.bones);
                    }

                }
            }
            
        }
    }

    /// <summary>  
    /// 遍历角色所有的骨骼节点来找到相对应得骨骼  
    /// </summary>  
    /// <returns></returns>  
    private void GetBone(Transform[] t)
    {
        foreach (Transform x in t)
        {
            foreach (Transform y in allBones)
            {
                if (y.name.Equals(x.name))
                {
                    boneList.Add(y);
                    break;
                }
            }
        }
    }
}

代码有在网上参考。


猜你喜欢

转载自blog.csdn.net/q568360447/article/details/79275112
今日推荐