【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游戏中人物换装解决方案
换装基本上是每个网游都必须有的一个功能,每种网游的做法都各有不同,有些是换掉整个模型,有些则是通过可以换掉模型的一个部分完成.前者属于整体换,相对简单些:后者则是通过部分替换实现,目前用的比较多,本文 ...
随机推荐
- CentOS系统时间修改
1. 实体机器上安装CentOS $date -s '2015-03-03 13:34:00' 2. 虚拟机上安装的CentOS #查看系统时间和硬件时间 date hwclock --show #设 ...
- 《AndroidStudio有用指南》反馈问题和建议
<AndroidStudio有用指南>反馈问题和建议 IntelliJ IDEA在持续更新, Android Studio也在持续更新, 本书也将会持续更新. Android Studio ...
- ubuntu 查看网卡 数据包处理 速度
ubuntu 查看网卡 数据包处理 速度 sar -l 1 10 首先要安装sar .使用 apt-get install atsar sar 命令中的 "-l"參数是 net-i ...
- tornado安全应用之用户认证
在这个例子中,我们将只通过存储在安全cookie里的用户名标识一个人.当某人首次在某个浏览器(或cookie过期后)访问我们的页面时,我们展示一个登录表单页面.表单作为到LoginHandler路由的 ...
- 配置tomcat,实现域名访问项目
首先,配置tomcat端口号为80,配置方法:配置tomcat,访问端口改为80 然后,配置访问项目时候,不用项目名,配置方法:配置tomcat,使访问项目时候无项目名 最后,配置tomcat的ser ...
- 代码空间项目 -- 获取当前时间之前的某一天-Calender类的使用
Calendar类的静态方法getInstance()可以初始化一个日历对象:Calendar now = Calendar.getInstance(); 1.Calendar的基本用法calenda ...
- socket 学习笔记
#include <sys/socket.h> ---------------------------------------------------------------------- ...
- requirejs测试
参考资料:http://www.ruanyifeng.com/blog/2012/11/require_js.html 一.文件目录 二.html <!DOCTYPE html> < ...
- jquery特效(5)—轮播图③(鼠标悬浮停止轮播)
今天很无聊,就接着写轮播图了,需要说明一下,这次的轮播图是在上次随笔中jquery特效(3)—轮播图①(手动点击轮播)和jquery特效(4)—轮播图②(定时自动轮播)的基础上写出来的,也就是本次随笔 ...
- LightOJ1234 Harmonic Number —— 分区打表
题目链接:https://vjudge.net/problem/LightOJ-1234 1234 - Harmonic Number PDF (English) Statistics Foru ...