Unity实现3D动态换装

一:原理

3D人物模型身上每个部位最重要的组件就是SkinnedMeshRenderer,它控制着此部位的外观显示,材质颜色以及骨骼的绑定等,其中有三个属性尤为重要:骨骼,网格,材质
Unity实现3D动态换装_第1张图片

对于动态的3D模型换装,我们需要更替新的Mesh并且绑定骨骼,以及更换新的材质
对于静态的3D模型换装,我们只需要替换Mesh和材质即可

 

二:代码的实现

——制作3D人物模型的预制体(包含每一个部位每一套衣服的SkinnedMeshRenderer组件和骨骼信息)和骨架预制体(只包含骨骼信息)
Unity实现3D动态换装_第2张图片

 


——实例化3D人物模型以及只有骨架的模型
注意骨骼节点信息必须保存下来为了之后绑定骨骼使用
Unity实现3D动态换装_第3张图片

 


——创建两个字典,一个存储每一种部位每一种服装的SkinnedMeshRenderer组件,一个存储骨骼模型身上的SkinnedMeshRenderer组件
编写存储各种信息的代码
Unity实现3D动态换装_第4张图片

 

——换装代码实现
注意必须进行骨骼绑定
Unity实现3D动态换装_第5张图片


——————————完整代码

using UnityEngine;
using System.Collections.Generic;

public class Manager : MonoBehaviour
{
    private GameObject source;//资源
    private GameObject skeleton;//骨架
    private Transform[] bones;//所有骨骼节点(绑定骨骼需要使用)
    private Dictionary dataDict = new Dictionary();//存储信息的字典
    private Dictionary smrDict = new Dictionary();//存储骨架身上的SkinnedMeshRenderer组件的字典
    private string[] str = { "face-1", "top-1", "shoes-1", "pants-1", "eyes-1", "hair-1" };

    private void Start()
    {
        Init();
    }

    //初始化
    private void Init()
    {
        source = Instantiate(Resources.Load("Model"));
        source.SetActive(false);
        skeleton = Instantiate(Resources.Load("Bones"));
        bones = skeleton.GetComponentsInChildren();
    }

    //存储信息
    private void SaveData()
    {
        foreach (SkinnedMeshRenderer smr in source.GetComponentsInChildren())
        {
            string[] names = smr.name.Split('-');
            if (!smrDict.ContainsKey(names[0]))
            {
                GameObject go = new GameObject(names[0]);
                go.transform.SetParent(skeleton.transform);
                smrDict.Add(names[0], go.AddComponent());
            }
            dataDict.Add(smr.name, smr);
        }
    }

    //换装
    private void ChangeDress(string name)
    {
        string[] names = name.Split('-');
        SkinnedMeshRenderer data = dataDict[name];

        List bonesList = new List();
        foreach (Transform trans in data.bones)
        {
            foreach (Transform bone in bones)
            {
                if (bone.name == trans.name)
                {
                    bonesList.Add(bone);
                    break;
                }
            }
        }
        smrDict[names[0]].bones = bonesList.ToArray();

        smrDict[names[0]].materials = data.materials;
        smrDict[names[0]].sharedMesh = data.sharedMesh;
    }
}

 

你可能感兴趣的:(Unity开发实战)