Unity实现换装功能

换装的核心思想:更换对象SkinnerMeshRenderer组件中骨骼(Bones),网格(sharedMesh),材质(materials)。麻烦的是要找到对应的部位,对应的SkinnerMeshRenderer组件,对应的位置。以下,介绍一种比较简单的换装过程。

通常要实现换装需要有一个带有“所有需要更换部件”的模型,如下:(图1)中FemaleModel为模型,其中Female_Hips为骨骼信息。(图2)为场景用的样子,可以看出它是很多重复部件的叠加物。


接下来说说具体的思路;

1.先制作骨骼模型

2.将原模型和骨骼模型实例化出来

3.建立字典存储所有SkinnerMeshRenderer信息

4.建立字典存储所有骨骼信息

5.将相应的信息存储在字典中

6.以名字进行一一对应,更换相应SkinnerMeshRenderer中三大件


接下来是每步详细步骤:

1.先制作骨骼模型

其实这部很简单,只需要将原模型中所有部件删除,只留下骨骼部分,如图:其中FemaleTarget就是骨骼模型


2.将原模型和骨骼模型实例化出来

    //原模型

    GameObject avatarModel;

    //骨骼模型

    GameObject avatarTarget;

    //所有骨骼信息

    Transform[] Hips;

void InitSys() {

 //实例化对应的模型并将其隐藏 

 avatarModel = Instantiate(Resources.Load("FemaleModel") as GameObject); avatarModel.SetActive(false); 

 //实例化要显示的对象并将其所有(骨骼)Transform信息收集 

 avatarTarget = Instantiate(Resources.Load("FemaleTarget") as GameObject); 

 Hips = avatarTarget.GetComponentsInChildren();

    }

3.建立字典存储所有SkinnerMeshRenderer信息

//存储模型的所有信息 //建立字典存储模型的SkinnerMeshRenderer信息

Dictionary> avaStr = new Dictionary>();

4.建立字典存储所有骨骼信息

//建立字典存储要显示对象的skinnerMeshRenderer信息

Dictionary avaSmr = new Dictionary();

5.将相应的信息存储在字典中

void SaveAvatarData() {

    SkinnedMeshRenderer[] skis = avatarModel.GetComponentsInChildren();

    foreach (SkinnedMeshRenderer ski in skis) {

    string[] names = ski.name.Split('-');

    //如果字典中没有存储这个部位

    if (!avaStr.ContainsKey(names[0])) {

    //那么就新建一个对象当做这个对象

    GameObject part = new GameObject();

    part.name = names[0];

    //set父级为要显示的任务骨骼

    part.transform.parent = avatarTarget.transform;

    //并且给它添加ski组件并加入字典中

    avaSmr.Add(names[0], part.AddComponent());

    //存入模型字典并实例化相应子字典

    avaStr.Add(names[0], new Dictionary());

    }

    //将序号和SkinnerMeshRenderer信息存入模型字典

    avaStr[names[0]].Add(names[1], ski); } }

6.以名字进行一一对应,更换相应SkinnerMeshRenderer中三大件

 //换装 

 //参数:换装部位名称,序号 

 void ChangeMesh(string name,string num) { 

 //从模型字典中拿到相应的SkinnerMeshRenderer 

 SkinnedMeshRenderer skm = avaStr[name][num]; 

 //创建集合来存储(骨骼)Transform信息

List<Transform> bones = new List<Transform>();

        foreach (var trans in skm.bones)

        {

            foreach (var bone in Hips)

            {

                if (bone.name == trans.name)

                {

                    bones.Add(trans);

                    break;

                }

            }

        }

        avaSmr[name].bones = bones.ToArray();

        avaSmr[name].materials = skm.materials;

        avaSmr[name].sharedMesh = skm.sharedMesh;

    }

至此,基本的换装的过程就此基本完成,接下来就是让要显示的模型有一个初始状态

7.先建立字典存储模型最初的状态:

//显示初始状态

    //建立数组

    string[,] avatar = new string[,] { {"face","1" }, { "top", "1" }, { "pants", "1" }, { "hair", "1" },

        { "eyes", "1" }, { "shoes", "1" } };

8.依次调用换装方法(注意此处遍历的是数组的行数而不是数组长度)

void InitAvatar()

    {

        for (int i = 0; i < avatar.GetLength(0); i++)

        {

            ChangeMesh(avatar[i, 0], avatar[i, 1]);

        }

    }

好了,现在试下调用如上方法就可以让模型显示出来啦。

void Start () {

        InitSys();

        SaveAvatarData();

        InitAvatar();

    }


进行换装就是调用ChangeMesh方法就好。如下举个小栗子~

void Update () {

        print(ani.isPlaying);

        if (Input.GetKeyDown(KeyCode.Space))

        {

            ChangeMesh("top", "2");

        }

}


Ps:这里还有一个问题就是模型的动画没有播放出来(虽然ani.isPlaying结果是true)。我怀疑是我中途换了Unity版本导致。就不深究啦~~

如上如果有任何不严谨或是错误的地方,欢迎各位指正~~嘻嘻~~

                                                                                                                                                                                                不忘初心的Tiny

                

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 最近都比较忙,没时间写,今晚利用空余时间分享一下游戏开发中常用的“换装”给大家,如果大家有什么好的插件或想法,记得...
    光明程辉阅读 10,799评论 1 7
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,272评论 19 139
  • 表妹毕业了,终于拿到了国际贸易专业的硕士毕业证书,而且英语专六,这样的底牌通过努力足以配得上她的未来。 家人不担心...
    Ms妮子眯眯阅读 3,878评论 0 2
  • http请求过程 域名解析 发起TCP的三次握手 建立TCP连接后发起 http 请求 服务器响应 http 请求...
    Sharise_Mo佩珊阅读 4,095评论 0 0
  • 不知道什么时候开始有一种丧文化悄然流行开来。 这些网络用语我相信大家应该听过不少。 什么“世上无难事,只要肯放弃”...
    诗人漫步uu阅读 3,214评论 0 1

友情链接更多精彩内容