【Unity3D】3D角色换装++ Advance
http://www.cnblogs.com/dosomething/archive/2012/12/15/2818897.html
本文在之前的文章Unity3D角色换装的原理 基础上做一个补充
 给出不同的解决方案
1、如果角色只是单纯的更换装备 也就是说 角色的整个身体是一个完整的网格 而所需要更换的各个部件只是装备 而不是身体的某一部分 比如NGUI中Character的例子 穿装备之前 角色只有默认的身体 穿了装备以后 身体不变 只是在特
定的位置显示装备 如下图
穿装备以前 穿装备以后
         
这样做的好处是实现起来很简单 就是在特定的骨骼下显示一个不含有蒙皮信息的装备模型
更换的时候去通知特定功能的代码去删掉或隐藏之前的 再显示新的即可
   不好的地方是 1 实现不了身体部件的更换 当然这不一定是不足 要视游戏的设计本身而论
2 穿上装备 实际上就是多增加了一份模型 那么所需要渲染的面数会增加 drawcall也会增加
   如果游戏中模型的面数以及drawcall控制的很好 并且不存在除角色以外的其他玩家换装的话 并且游戏本身设计时也不需要身体部件更换的话 
那这样做应该会是个值得考虑的方案
2、大部分网络游戏都会选择将身体的各个部件拆开 各个部件由身体部分和装备部分共同组成一个完整的模型 因此更换部件其实也就是更换装备
unity实现就如同上文中所讲 代码可参考官方CharacterCustomization例子
在游戏中 关心的不仅是装备有没有更换 更关心更换的好不好 会不会留有隐患
官方的这个例子只是演示了换装的原理 但是打开profile的memory一栏 会看到在更换装备的时候 内存占用在不断的增加
这样无厘头的内存占用会带来严重的后果 尤其是网络游戏这种换装频率高的游戏方式 尤其对于移动平台的网络游戏 尤其对于移动平台的3d网络游戏
优化问题牵扯到内存优化 资源优化 渲染优化 代码优化等多方面 待后文中再逐一讨论
官方换装中的内存问题 是因为装备被替换掉以后 没有从内存中清除 不断的更换就会在内存中不断的累加
   相关问题在unity圣殿中有文章详细解释
装备中除武器以外 其他的部分都可以用同一种方式去更换 当然武器也可以 同样要视游戏本身而论
如果游戏中在安全区需要武器背在背上 而在非安全区拿在手上 同时有角色的“亮出武器”这样的过度动作配合 那么一个角色身上装备两把武器绝对是不二之选 一把在手上 一把在背上 控制其中之一显示即可 那么在更换武器的时候则需要将这两把武器全部更新
如果只是一把武器 在不同的状态挂在不同的位置的话 那么unity实现中一个很好的办法就是单纯的把武器模型放到相应的骨骼下 成为该骨骼的sub node
身体各部件都需要能够支持动态的更换 按照官方的例子 实际上更换每一个部件 就等同于重新合并了一遍网格 只是这次合并是用新装备的模型和其他部件的模型
当然如果选择不合并网格 那么也就是说 每个装备的部件都有一个SkinnedMeshRenderer组件来与骨骼进行关联 等同于计算量会翻倍
合并网格的换装代码参考官方实例 不合并网格的换装核心代码如下 即从当前角色的骨骼中取到该模型所关联的骨骼 然后建立关联即可
public void Generate(GameObject root, int elemId)
{
if (root == null)
return; // Return if current map doesnt contain this element
if (!elementDict.ContainsKey(elemId) || elementDict[elemId] == null) return; // Get element's SkinnedMeshRenderer component
SkinnedMeshRenderer elemSmr = elementDict[elemId].GetSkinnedMeshRenderer();
// To be sub-object
elemSmr.gameObject.transform.parent = root.transform;
// All bones in this root
Transform[] bones = root.GetComponentsInChildren<Transform>();
// All bones needed by element
List<Transform> elemBones = new List<Transform>();
// All bone name in this element
string[] elemBoneNames = elementDict[elemId].GetBoneNames(); // Find matched bones in root
for (int i = 0; i < elemBoneNames.Length; ++i)
{
for (int j = 0; j < bones.Length; ++j)
{
if (string.Compare(bones[j].name, strBone) == 0)
{
elemBones.Add(bones[j]);
break;
}
}
}
elemSmr.bones = elemBones.ToArray();
elemSmr.updateWhenOffscreen = false;
【Unity3D】3D角色换装++ Advance的更多相关文章
- Unity3d 3d角色换装实现原理及步骤
		
http://www.cnblogs.com/dosomething/archive/2012/04/15/2450526.html 1.角色模型制作 unity3d支持Skin动画 但是不支持Ph ...
 - 【Unity3d】3d角色换装实现原理及步骤
		
http://www.cnblogs.com/dosomething/archive/2012/04/15/2450526.html 1.角色模型制作 unity3d支持Skin动画 但是不支持Ph ...
 - unity 角色换装
		
unity角色换装的关键是更改角色部位上的物体的SkinnedMeshRenderer组件的属性: 更改mesh:mesh决定了部位的物体的外形,是主要的数据. 刷新骨骼:同一个部位下,不同的mesh ...
 - Unity3D教程:换装方法
		
http://www.manew.com/4136.html 游戏内的角色,能够像纸娃娃换装那样子让玩家可以为自己的角色改变外观,一直是相当受欢迎的功能:一般而言,我们建好的 3D 模型,如果要将其中 ...
 - 浅谈角色换装功能--Unity简单例子实现
		
在前置篇中,基本上梳理了一下换装功能背后涉及到的美术工作流.但程序员嘛,功能终归是要落到代码上的.本文中会结合Unity提供的API及之前提到的内容来实现一个简单的换装功能.效果如下: (图1:最终效 ...
 - Unity动态换装之Spine换装
		
注:转载请注明转载,并附原链接 http://www.cnblogs.com/liaoguipeng/p/5867510.html 燕双飞情侣 一.动态换装原理 换装,无非就是对模型的网格,或者贴图进 ...
 - Unity3d 换装Avatar系统
		
原理就是用新造的部件和角色的骨骼进行重新对接. demo的使用方法: PartIdx设置要换那个部件[0,4],一共5个部件 EquipIdx设置要更换部件的装备索引[0,1],具体看我的Change ...
 - Unity3d 换装 之 模型动画分离
		
在手游中换装成了越来越不可缺的一个功能,毫无疑问各式各样的时装为游戏增添了不同的色彩. 对于2D手游,或许是更换对应的序列帧,也或许是如同3D手游一般,更换模型动画. 对于游戏中的人物,一般分为头.上 ...
 - 3D游戏中人物换装解决方案
		
换装基本上是每个网游都必须有的一个功能,每种网游的做法都各有不同,有些是换掉整个模型,有些则是通过可以换掉模型的一个部分完成.前者属于整体换,相对简单些:后者则是通过部分替换实现,目前用的比较多,本文 ...
 
随机推荐
- slidemenu
			
1. 在github上有一个效果不错的开源库,SlidingMenu 最新的代码下载下来后,会报错: No resource found that matches the given name: at ...
 - JQuery日记 5.31 JQuery对象的生成
			
JQuery对象的生成 1 selector为不论什么可转换false的空值 返回空JQuery对象 2 selector为字符串 2.1 selector为html字符串或有id属性的标签 ...
 - VB.NET版机房收费系统—数据库设计
			
之前第一遍机房收费的时候,用的数据库是别人的.认知也仅仅能建立在别人的基础上,等自考中<数据库系统原理>这本书学完了之后,再去看曾经的数据库,发现数据库真的还须要进一步的优化.以下是我设计 ...
 - 【windows phone】CollectionViewSource的妙用
			
在windows phone中绑定集合数据的时候,有时候需要分层数据,通常需要以主从试图形式显示.通常的方法是将第二个ListBox(主视图)的数据源绑定到第一个ListBox (从视图)的Selec ...
 - EasyDarwin Streaming Server对Task的调用方法
			
我们在EasyDarwin流媒体服务器的二次开发过程中,经常会需要定义自己的Task类,例如在EasyDarwin中,RTSPSessioin.HTTPSession.RTCPTask等,都是Task ...
 - 开源G711(PCMA、PCMU)/G726转AAC项目EasyAACEncoder
			
EasyDarwin开源社区整理了一份G711(PCMA.PCMU)/G726转AAC的转码库,支持Windows/Linux跨平台使用,将安防标准的G711转成移动互联网常用的AAC格式,希望能给大 ...
 - MongoDB复制集架构搭建
			
创建目录 mkdir -p /data/r0 /data/r1 /data/r2 声明实例 ./bin/mongod --port 27017 --dbpath /home/workspace/dat ...
 - ActiveMQ的消息的(含附件)发送和接收使用
			
首先介绍一下ActiveMQ的版本:apache-activemq-5.10.2 启动MQ:activemq.bat 下面来编写MQ的发送类: 里面的发送ip和模式名称可以根据具体的实际情况填写. S ...
 - 【C语言天天练(十九)】restrict关键词
			
引言:在内核的系统调用函数里,常常遇到函数的參数使用restrict限定词限定的情况,以下就对该关键词做个总结. 1.restrict关键词是C99特性才加入的,因此在编译使用含有该限定词的程序时,一 ...
 - 代码空间项目 -- cookie的基本使用
			
cookie在日常开发b/s架构时候经常使用,可以在记住用户,方便自动登录,也可以记住用户的偏好并对应推送广告 下面说说开发时候的基本用法: 1.创建cookie//设置cookie,键值对形式Coo ...