Unity3D手游开发日记(11) - 基于共享骨骼简单高效的换装方案
2017-04-26 20:33
344 查看
游戏的换装,一般分为3种.换材质,骨骼挂接,共享骨骼.用的比较多的是骨骼挂接和共享骨骼.
1.骨骼挂接
没有动作的骨骼挂接,适合武器.
有动作的骨骼挂接,适合坐骑.
2.共享骨骼
共享骨骼,适合身体部件.主模型(身体)包含整个骨骼,部件模型只包含自己部分的骨骼,应用的时候,部件模型的骨骼共享主模型的骨骼.这样的话,只需要播放主模型的动画,部件会跟着动.
Unity的换装呢,你要百度一下,能搜出一堆文章,方法也是多种多样.有参考价值的却不多.
比如主流推荐的官方demo提供的换装方式.合并mesh,多此一举又麻烦.
比如avatar的方式 ...不适合Legacy动画
其实用以前端游的方式,共享骨骼就行了,Ogre引擎直接提供函数OGRE::shareSkeletonInstanceWith()来实现.而Unity引擎没有这个函数,怎么办呢,自己写一个呗.命名我也取一样的,表示对Unity自己不封装这个函数的鄙视.
代码很简单,原理我再结合Unity仔细分析下.
第一步 :
假设整个模型分两部分,身体和翅膀,身体作为主模型,翅膀作为部件模型,身体30根骨骼,翅膀6根骨骼,总数量36根骨骼.
1.导出身体模型的时候,选中身体和整个骨骼(注意是整个骨骼),这样身体也包含了翅膀的骨骼.
2.导出翅膀模型的时候,选中翅膀和翅膀骨骼(翅膀不用导整个骨骼).
第二步:
模型有哪些骨骼,可以放入Unity查看root下面的节点 ,这里有个注意的地方,通过SkinnedMeshRenderer.bones查看的骨骼数量总是比通过root节点查看的数个数量少,因为SkinnedMeshRenderer.bones保存的模型真正用到的骨骼,而不是整个骨骼,比如身体模型的SkinnedMeshRenderer.bones只有30,而不是36.
第三步:
平级挂接2个模型到同一个父节点下测试,播放身体模型的动画,身体会动,翅膀不会,很正常,因为动的是身体模型的骨骼,翅膀模型的骨骼根本就没动.接下来把翅膀模型的6个骨骼设置成身体模型对应的那6个骨骼的transform,再播放,就发现翅膀也跟着动了,所谓共享,就是对应的把自己的骨骼设置成目标的骨骼.
函数调用很简单 ShareSkeletonInstanceWith(翅膀, 身体)
原文地址:http://blog.csdn.net/qq18052887/article/details/52648909
1.骨骼挂接
没有动作的骨骼挂接,适合武器.
有动作的骨骼挂接,适合坐骑.
2.共享骨骼
共享骨骼,适合身体部件.主模型(身体)包含整个骨骼,部件模型只包含自己部分的骨骼,应用的时候,部件模型的骨骼共享主模型的骨骼.这样的话,只需要播放主模型的动画,部件会跟着动.
Unity的换装呢,你要百度一下,能搜出一堆文章,方法也是多种多样.有参考价值的却不多.
比如主流推荐的官方demo提供的换装方式.合并mesh,多此一举又麻烦.
比如avatar的方式 ...不适合Legacy动画
其实用以前端游的方式,共享骨骼就行了,Ogre引擎直接提供函数OGRE::shareSkeletonInstanceWith()来实现.而Unity引擎没有这个函数,怎么办呢,自己写一个呗.命名我也取一样的,表示对Unity自己不封装这个函数的鄙视.
// 共享骨骼 public static void ShareSkeletonInstanceWith(SkinnedMeshRenderer selfSkin, GameObject target) { Transform[] newBones = new Transform[selfSkin.bones.Length]; for (int i = 0; i < selfSkin.bones.GetLength(0); ++i) { GameObject bone = selfSkin.bones[i].gameObject; // 目标的SkinnedMeshRenderer.bones保存的只是目标mesh相关的骨骼,要获得目标全部骨骼,可以通过查找的方式. newBones[i] = FindChildRecursion(target.transform, bone.name); } selfSkin.bones = newBones; } // 递归查找 public static Transform FindChildRecursion(Transform t, string name) { foreach (Transform child in t) { if (child.name == name) { return child; } else { Transform ret = FindChildRecursion(child, name); if (ret != null) return ret; } } return null; }
代码很简单,原理我再结合Unity仔细分析下.
第一步 :
假设整个模型分两部分,身体和翅膀,身体作为主模型,翅膀作为部件模型,身体30根骨骼,翅膀6根骨骼,总数量36根骨骼.
1.导出身体模型的时候,选中身体和整个骨骼(注意是整个骨骼),这样身体也包含了翅膀的骨骼.
2.导出翅膀模型的时候,选中翅膀和翅膀骨骼(翅膀不用导整个骨骼).
第二步:
模型有哪些骨骼,可以放入Unity查看root下面的节点 ,这里有个注意的地方,通过SkinnedMeshRenderer.bones查看的骨骼数量总是比通过root节点查看的数个数量少,因为SkinnedMeshRenderer.bones保存的模型真正用到的骨骼,而不是整个骨骼,比如身体模型的SkinnedMeshRenderer.bones只有30,而不是36.
第三步:
平级挂接2个模型到同一个父节点下测试,播放身体模型的动画,身体会动,翅膀不会,很正常,因为动的是身体模型的骨骼,翅膀模型的骨骼根本就没动.接下来把翅膀模型的6个骨骼设置成身体模型对应的那6个骨骼的transform,再播放,就发现翅膀也跟着动了,所谓共享,就是对应的把自己的骨骼设置成目标的骨骼.
函数调用很简单 ShareSkeletonInstanceWith(翅膀, 身体)
原文地址:http://blog.csdn.net/qq18052887/article/details/52648909
相关文章推荐
- Unity3D手游开发日记(11) - 基于共享骨骼简单高效的换装方案
- Unity3D手游开发日记(11) - 基于共享骨骼简单高效的换装方案
- 快速实现简单高效并可以灵活配置的URL重写方案(附源代码)
- 【水晶报表之图片篇-c】 CR 11版本动态加载的另一种简单方案
- 项目分布式部署那些事(2):基于OCS(Memcached)的Session共享方案
- Android 毛玻璃(高斯模糊) 开源控件。简单、快速、高效。(基于fastblur)
- createjs支持spine骨骼的简单封装(更新,加入换装)
- 快速实现简单高效并可以灵活配置的URL重写方案(附源代码)
- 基于MSM session 共享tomcat集群方案
- 【水晶报表之图片篇-c】 CR 11版本动态加载的另一种简单方案
- 单点登录三个方法及原理:共享Session、基于OpenId的单点登录、基于Cookie的OpenId存储方案
- 简单的基于IIS7的web server NLB方案
- 基于Asp.NET MemberShip的简单SSO方案
- sencha touch 高性能 list最简单高效的实现方案
- 云服务器之间实时文件同步和文件备份的最简单高效的免费方案
- 简单高效的病毒清除方案(图文教程)
- 基于Asp.NET MemberShip的简单SSO方案
- 邮件服务器-POP3服务器邮件索引/UIDL简单、高效的缓存方案
- ubuntu上构建简单的基于http的文件共享服务
- 基于Spring打造简单高效通用的异步任务处理系统