如何优化Unity3d中的武器系统

24317人阅读
Unity 3D(25)
项目进入了中期之后,就需要对程序在移动设备上的表现做分析评估和针对性的优化了,首先前期做优化,很多瓶颈没表现出来,能做的东西不多,而且很多指标会凭预想,如果太后期做优化又会太晚,到时发现一些问题改起来返工量就有太大。前一阵子花了大量时间从 cpu gpu 内存 启动时间 到发热量对项目做了一翻大规模的体检和优化,效果还是显著的,在这里做个笔记,以后开发项目时可以作为经验和提前关注
& & & 1.项目情况:笔者所在项目是一个非常重度的手游,甚至开始就是瞄着端游做的,3D世界,2.5D视角,RPG,即使战斗,美术品质要求极高(模型 贴图精度高 ,超过目前市场同类产品)。对于目前大多数移动设备来看,挑战不小,对手机的各种硬件都是挑战。、
& & &2.目标机型:偏中高端,尽量兼容低端,android至少sumsung S3能流畅,ios至少iphone4s流畅。
& & &3.性能指标:内存占用250M以下(这样大量512的机器不会挂掉),初始包100m之内(太多运营不干,太少实在是装不下。。)
用于分析和测试性能的一些利器:
&1.首先是unity在编辑器下的statics窗口:提供了dc和顶点数这两个重要指标的查看。缺点在设备看不到,但是对于dc数和顶点数来说,设备和编辑器差不多,用它可以大体看出渲染的压力。
&2.unity自带的profiler:可以连接设备看到设备上cpu gpu mem的信息,使用的时候需要勾选development模式。有点是cpu的占用在脚本的层面看的非常仔细,哪个函数占用了太多时间一眼就能看出,基本是分析脚本效率的最佳工具,但是gpu大部分设备不支持看不到,显示的mem信息不太准确,基本上偏离实际占用的内存
3.unity的internal profiler:在playersetting上可以勾选这个选项,勾选后,连接设备,在android的adb或者mac的xcode里会每隔几秒打印出很多关键指标,这个其实非常有用,不过这个功能直到很后期才发现,详细文档见
4.android上的adb:adb提供了一组非常强大的分离android程序的工具,
而最常用的是用adb的dumpsys 指令,
最常见的包括: adb shell dumpsys meminfo appname &查看实时的内存占用,android的内存分为ps rs,我们一般看ps为准,关于ps rs这些概念可参看
adb shell dumpsys cpuinfo appname 查看实时的cpu占用,注意这里的cpu可能过百,这是因为多核的原因
adb shell dumpsys gpuinfo appname 查看实时的gpu情况
5.android &的monitor
安装adt后,在sdk\tools\monitor.bat下面有个monitor,是我认为android看性能最好的工具之一,因为它是图形化的,而且基本集成了adb的功能,从内存到cpu到gpu,还有很有用的网络流量使用情况,它的cpu占用是c++层面的统计,看不到脚本,这需要突破那个profilor结合。
6.android上的mongkey测试:它可以模拟随机的用户输入,用来验证你的程序的强壮性吧
adb shell monkey -p -v packname 1000
随机模拟1000条用户事件
7.ios:ios上的工具则显得更加专业更加统一一些,ios就用xcode自带的instruments了
这里有个详细的文档
看来这么多工具,其实很多是要配合使用的,做u3d开发,其实不只是学会U3D的事情,要让U3D在手机上运行的好,还需要对各个平台有较深的了解。
&利用这些工具法线了一些瓶颈,同时也采取了各种策略来提高性能,反正目标就是cpu占用降低,内存占用减少,启动快,发热小,帧率高,GPU占用少,发现的一些问题和做出的具体的一些努力列举如下:
1.使用assetbundle,实现资源分离和共享,将内存控制到200m之内,同时也可以实现资源的在线更新
2.顶点数对渲染无论是cpu还是gpu都是压力最大的贡献者,降低顶点数到8万以下,fps稳定到了30帧左右
3.只使用一盏动态光,不是用阴影,不使用光照探头
粒子系统是cpu上的大头
4.剪裁粒子系统
5.合并同时出现的粒子系统
6.自己实现轻量级的粒子系统
animator也是一个效率奇差的地方
7.把不需要跟骨骼动画和动作过渡的地方全部使用animation,控制骨骼数量在30根以下
8.animator出视野不更新
9.删除无意义的animator
10.animator的初始化很耗时(粒子上能不能尽量不用animator)
11.除主角外都不要跟骨骼运动apply root motion
12.绝对禁止掉那些不带刚体带包围盒的物体(static collider&)运动
NUGI的代码效率很差,基本上runtime的时候对cpu的贡献和render不相上下
13每帧递归的计算finalalpha改为只有初始化和变动时计算
14去掉法线计算
15不要每帧计算viewsize 和windowsize
16filldrawcall时构建顶点缓存使用array.copy
17.代码剪裁:使用strip level ,使用.net2.0 subset
18.尽量减少smooth group
19.给美术定一个严格的经过科学验证的美术标准,并在U3D里面配以相应的检查工具
后面的文章会对这些点做以更详细的讨论
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:725757次
积分:6623
积分:6623
排名:第3499名
原创:130篇
转载:18篇
评论:139条
文章:24篇
阅读:187020
(2)(3)(1)(1)(1)(7)(1)(3)(2)(2)(1)(1)(3)(4)(1)(1)(2)(1)(9)(1)(5)(3)(3)(7)(7)(3)(3)(11)(1)(1)(2)(1)(1)(4)(3)(3)(1)(3)(5)(3)(2)(3)(9)(3)(3)(1)(6)(1)(2)(1)MagicaVoxel 导入到 Unity 的模型如何优化面数【unity3d吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:74,071贴子:
MagicaVoxel 导入到 Unity 的模型如何优化面数收藏
MagicaVoxel 导出的Obj文件的贴图方式很特别,下图模型的贴图只是个简单的1X256的“面条”(如图3),这种设计有很多好处,比如方便全局调整颜色、所有物体可以共用一个材质球……但是有个致命缺陷:在某些情况下会很浪费模型面数。图1中的墙只是一个平面而已,因为颜色不同就多了好多面,这种浪费(外加本人优化太渣)让Unity跑不动图2中的场景,不bake的话,全屏帧数掉到10~20,绝大部分CPU资源都浪费在等待GPU上,而GPU在忙着处理光照和阴影信息(关掉墙上的5盏灯后果断20~40FPS)。然而不能消极的解决问题。。。有没有什么办法,能比较舒服的解决这个问题?其实就是改用传统的贴图方式,不过不能手动操作这上百个模型,有什么优化面数的插件可用吗?(AssetStore里有个专门为MagicaVoxel设计的面数优化插件,不过不能解决这个问题)【图1】【图2】【图3】上图模型的贴图就是这个了,并不像传统的贴图方式那样的 尽可能减少面数,MV是在尽可能减小贴图的复杂度。
用Voxelshop导
登录百度帐号推荐应用unity3d优化总结篇
1. 更新不透明贴图的压缩格式为ETC 4bit,因为android市场的手机中的GPU有多种,每家的GPU支持不同的压缩格式,但他们都兼容ETC格式,
2. 对于透明贴图,我们只能选择RGBA 16bit 或者RGBA 32bit。
3. 减少FPS,在ProjectSetting-& Quality中的VSync Count 参数会影响你的FPS,EveryVBlank相当于FPS=60,EverySecondVBlank = 30;这两种情况都不符合游戏的FPS的话,我们需要手动调整FPS,首先关闭垂直同步这个功能,然后在代码的Awake方法里手动设置FPS(Application.targetFrameRate = 45;)降低FPS的好处:1)省电,减少手机发热的情况;2)能都稳定游戏FPS,减少出现卡顿的情况。
4. 当我们设置了FPS后,再调整下Fixed timestep这个参数,这个参数在ProjectSetting-&Time中,目的是减少物理计算的次数,来提高游戏性能。
5. 尽量少使用Update LateUpdate FixedUpdate,这样也可以提升性能和节省电量。多使用事件(不是SendMessage,使用自己写的,或者C#中的事件委托)。
6. 待机时,调整游戏的FPS为1,节省电量。
7. 图集大小最好不要高于1024,否则游戏安装之后、低端机直接崩溃、原因是手机系统版本低于2.2、超过1000的图集无法读取、导致。2.2 以上没有遇见这个情况。注意手机的RAM 与 ROM、小于 512M的手机、直接放弃机型适配。VSCount 垂直同步Unity3D中新建一个场景空的时候,帧速率(FPS总是很低),大概在60~70之间。一直不太明白是怎么回事,现在基本上明白了。我在这里解释一下原因,如有错误,欢迎指正。在Unity3D中当运行场景打开Profiler的时候,我们会看到VSync 这一项占了很大的比重。这个是什么呢,这个就是垂直同步,稍后再做解释。我们可以关闭VSync来提高帧速率,选择edit-&project settings-&Quality。
在右侧面板中可以找到VSync Count,把它选成Don't Sync。
这就关闭了VSync(垂直同步),现在在运行场景看看,帧速率是不是提高很多。现在来说说什么是垂直同步,要知道什么是垂直同步,必须要先明白显示器的工作原理,显示器上的所有图像都是一线一线的扫描上去的,无论是隔行扫描还是逐行扫描,显示器都有两种同步参数——水平同步和垂直同步。什么叫水平同步?什么叫垂直同步?垂直和水平是CRT中两个基本的同步信号,水平同步信号决定了CRT画出一条横越屏幕线的时间,垂直同步信号决定了CRT从屏幕顶部画到底部,再返回原始位置的时间,而恰恰是垂直同步代表着CRT显示器的刷新率水平。为什么关闭垂直同步信号会影响游戏中的FPS数值?如果我们选择等待垂直同步信号(也就是我们平时所说的垂直同步打开),那么在游戏中或许强劲的显卡迅速的绘制完一屏的图像,但是没有垂直同步信号的到达,显卡无法绘制下一屏,只有等85单位的信号到达,才可以绘制。这样FPS自然要受到操作系统刷新率运行值的制约。而如果我们选择不等待垂直同步信号(也就是我们平时所说的关闭垂直同步),那么游戏中作完一屏画面,显卡和显示器无需等待垂直同步信号就可以开始下一屏图像的绘制,自然可以完全发挥显卡的实力。但是不要忘记,正是因为垂直同步的存在,才能使得游戏进程和显示器刷新率同步,使得画面更加平滑和稳定。取消了垂直同步信号,固然可以换来更快的速度,但是在图像的连续性上势必打折扣。这也正是很多朋友抱怨关闭垂直后发现画面不连续的理论原因。合并材质球unity 3d中每倒入一次模型就多一个材质球,可我的这些模型都是共用一张贴图的就想共用一个材质球,所以每次都要删除再附上,很麻烦。怎么才能合并这些材质球?采用TexturePacking吧
1、遍历gameobject,取出material,并根据shader来将material分类
2、调用Unity自带的PackTextures函数来合并每个shader分类中的material所对应的textures(PackTextures函数有缺陷,不过可以将就用) 3、根据合并的大的texture来更新原有模型的texture、material已经uv坐标值。需要注意的是:需要合并的纹理应该是物体在场景中距离相近的,如果物体在场景中的距离较远,则不建议合并纹理,因为这样做很有可能非但起不到优化的作用,反而降低了运行效率。
责任编辑:
声明:本文由入驻搜狐号的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
今日搜狐热点今天看啥 热点:
用UNITY开发手机游戏,背景图片和UI图片显示的比PC机上模糊很多,怎么解决??
在unity里选中资源&
1.TextureType 改成 Advanced
2.NonPower of 2 改成 non
3.把 generate Mip maps 的勾去掉
4.Format压缩格式 选中rgba32bit
5.保存下 apply&
/archives/1019 &在unity中播放视频 用到 moivetexture
删除多余内存垃圾
GC.Collect();卸载0代垃圾
GC.Collect(1);卸载1代垃圾
GC.Collect(2);卸载2代垃圾
Resources.UnloadUnusedAssets (卸载未使用的资源)
传个true作为参数貌似可以卸载所有的
Unity3d的Player setting中包括一个选项“Submit HW Statistics”,根据这个选项,Unity收集到了很多设备状态信息,并公开给大家形成参考资料。Mobile设备地址,1、iOS&http://t.cn/zRq6uXK&;2、Android&http://t.cn/zTqKwLr&;各位参考吧。
/mobile/index.html
/mobile/index-ios.html
Unity的C#脚本中GetComponentsInChildren&&()能够获取一个物体所有子物体的元素集合
Vector3的变量是Float,单精度浮点小数。
GameObject. AddComponent为新产生的物体添加一个脚本
发布Android应用时,PlayerSettings中必须更改Bundle Identifier
使用PlayerPrefs类提供的方法可以把当前游戏的数据保存到本地
想要在当前场景的基础上叠加加载一个新的场景,使用Application.LoadLevelAdditive();
如果是希望场景中某个对象不被释放:
DontDestroyOnLoad(GameObject.Find(&UI Root&));
Application.LoadLevel(&Home&);
在Edit→Preference中的General选项卡下勾选Always show Project Wizard可以使Unity在一台机器上启动多个程序实例
Camera.WorldToScreenPoint可以把物体的世界坐标转换成相机的屏幕坐标
需要添加到物体上的脚本必须继承自MonoBehavior
gameObject.transform内部机制相当于是find,一直觉得很扯蛋,不知道官方为什么要这么做,非要用户自己做一个引用变量,gameObject.transform这样不能是引用
面象对象的语言有自动垃圾销毁功能,但有的变量必须手动销毁,像某些情况下的数组里的元素,还有就是游戏对象,不用时也得手动销毁哦,制作游戏时敌人尽量保持一定的数量,达到动态平衡,而不是越来越多,最终导致死机。
u3d打包时 资源里面的它都打包 所以不必要的物件尽量删除 &
怎么去掉pc上开启游戏时候的
File - Build Settings -Pc and Mac Standalone -Player Settings -Resolution and Presentation -Display Resolution 选项改为 Dialog Disabled & & &
Edit-&Project setting-&player 下选中有windows标志的那个图标,在resolution and presentation下display resolution 为disable &
一些Unity的使用和优化心得(大部分内容摘自网络)&
下面由一个基础的问题引出全文(题目与解答由Jare师父提供):&
有两段代码,循环执行两个比较耗时的方法,假设语言和编译器相同,哪一段会比较快?&
for (int i = 0; i & 100; i++)&
&& &DoSomethingA();&
&& &DoSomethingB();&
for (int i = 0; i & 100; i++)&
&& &DoSomethingA();&
for (int i = 0; i & 100; i++)&
&& &DoSomethingB();&
相信有很多人一样,第一眼看起来认为第一段更快点。但实际上答案是第二段快。原因如下:&
在这里性能的瓶颈不是循环本身。而是里面的方法。&
如果重复执行一个方法,那么CPU的寄存器、一级、二级缓存都很容易命中,比起到内存拿数据快多了。&
如果执行完一个执行另一个,那么缓存很可能就被替换掉了,只能到内存拿,甚至内存不够,要到硬盘上的虚拟内存拿。&
缓存组件查找(以下内容摘自网络)&
这种优化需要一些代码并且不是总有必要。但是如果你的代码真的很大,并且你需要尽可能的性能提升,它会是很好的优化。&
当你通过GetComponent获取一个组件或一个变量时,Unity必须从游戏物体里找到正确的组件。这时你便能通过一个缓存组件引用到一个私有变量。&
void Update () {&
&& &transform.Translate(new Vector3(0, 0, 5));&
private Transform myT&
void Awake () {&
&& &myTransform =&
void Update () {&
&& &myTransform.Translate(new Vector3(0, 0, 5));&
后面的代码运行较快,因为Unity不用在每一帧寻找变换组件。同样,支持脚本组件。你可以使用GetComponent获取组件或其他快捷属性。&
一个Mesh 建议使用的面数在 之间。&
一个 Mesh 建议只用一个 Material。&
注意:两个Mesh结合成一个Mesh,但是却使用两个Material,并不会提高效能。&
如果要提高效能必须把这两个Mesh的Material也合并成一个。&
换句话说,一个Mesh使用多个Material 和一个Material 使用多个render,其实耗能是差不多的。&
所以,尽可能的让物件共用相同的Texture 才是提升效能的根本之道。&
把物体设为static可以提高渲染效率,缺点是不能使用动态uv(可能还有别的缺点,不过没试过)&
&1. 尽量避免每帧处理&
function Update() { DoSomeThing(); }&
可改为每5帧处理一次:&
function Update() { if(Time.frameCount % 5 == 0) { DoSomeThing(); } }&
2. 定时重复处理用 InvokeRepeating 函数实现&
比如,启动0.5秒后每隔1秒执行一次 DoSomeThing 函数:&
function Start() { InvokeRepeating(&DoSomeThing&, 0.5, 1.0); }&
3. 优化 Update, FixedUpdate, LateUpdate 等每帧处理的函数&
函数里面的变量尽量在头部声明。&
function Update() { var pos: Vector3 = transform. }&
private var pos: Vector3; function Update(){ pos = transform. }&
4. 主动回收垃圾&
给某个 GameObject 绑上以下的代码:&
function Update() { if(Time.frameCount % 50 == 0) { System.GC.Collect(); } }
5. 运行时尽量减少 Tris 和 Draw Calls&
预览的时候,可点开 Stats,查看图形渲染的开销情况。特别注意 Tris 和 Draw Calls 这两个参数。&
一般来说,要做到:&
Tris 保持在 7.5k 以下&
Draw Calls 保持在 20 以下&
6. 压缩 Mesh&
导入 3D 模型之后,在不影响显示效果的前提下,最好打开 Mesh Compression。&
Off, Low, Medium, High 这几个选项,可酌情选取。&
7. 避免大量使用 Unity 自带的 Sphere 等内建 Mesh&
Unity 内建的 Mesh,多边形的数量比较大,如果物体不要求特别圆滑,可导入其他的简单3D模型代替。&
8. 优化数学计算&
比如,如果可以避免使用浮点型(float),尽量使用整形(int),尽量少用复杂的数学函数比如 Sin 和 Cos 等等。&
使用#pragma strict&
现在问题是,你通常不会意识到你在使用动态类型。#pragma strict可以解决这个问题!简单的添加#pragma strict在脚本顶部,之后Unity将禁用脚本的动态类型,强制你使用静态类型。如果有一个类型未知,Unity将报告编译错误。下面,foo将在编译时报错:&
#pragma strict&
function Start ()&
&& &var foo = GetComponent(MyScript);&
&& &foo.DoSomething();&
使用内置数组&
内置数组是非常快的。ArrayList或Array类很容易使用,你能轻易添加元件。但是他们有完全不同的速度。 内置数组有固定长度,并且大多时候你会事先知道最大长度然后填充它。内置数组最好的一点是他们直接嵌入结构数据类型在一个紧密的缓存里,而不需要任何额外类型信息或其他开销。因此,在缓存中遍历它是非常容易的,因为每个元素都是对齐的。&
privatevar positions : Vector3[];&
function Awake () {&
&& &positions = new &Vector3[100];&
&& &for (var i=0;i&100;i++)&
&& &positions = &Vector3.&
未选中物体变灰色:
改变物体shader中最后计算出来的rgb值即可,将其转换成lab,然后用(l,l,l)来代表其最终的rgb即可,对于选中的物体不需要进行处理,这样就会出现上述的视觉效果了&
代码如何控制是否使用lightmaps
unity是通过shader来加载lightmap的,你可以设置一个全局参数来控制是否需要lightmap进行最后的光照计算,然后通过白天还是夜晚控制这个全局参数即可。
billboard:
公告版.transform.LookAt(new Vecter3(Camera.main.transform.position.x,公告版.transform.position.y,Camera.main.transform.z))。这个方法hog在论坛里发过&
1、角色模型制作
  unity3d支持Skin动画 &但是不支持Physique动画 &会发现Physique动画在unity里严重变形 &
  因此在模型的骨骼动画的制作上面 &要用Skin &
  当然也可以做成Physique &然后用插件转换一下 &3dsmax的插件PhyToSkin
  3dsmax中转换之前 &为了避免出错 &先隐藏骨骼 & 然后对绑定了骨骼的模型进行单独转换 &因为批量也会出错
  转换以后在修改面板中加入可编辑网格 &同时为了避免出错 &检查一下uv是否贴反了
2、角色模型导出
  确保导出的模型是已经绑定了骨骼的 &在导出设置中根据需要选择是否导出Animation &
  以及3dsmax和unity3d中的单位关系
& & &备注:max中导出戴有骨骼动画的mesh:
1 导出时需包含骨骼信息和mesh,mesh包含对应的skin影响器,physique不支持。
2 导出时在导出面板勾选导出动画,并设置要导出的动画时间长度
& & max中单位: &按1unit=1m制作,之后导出设置单位为M,这样缩放因子在1则为正确。fbx进入unity中后,模型要将缩放因子由0.01 改为1,则单位与max中 的单位以及真实世界的单位对齐了
3、官方CharacterCustomization中的模型
  从官方换装demo中会发现他的一个角色模型里包含了要换装的多个模型 &比如有两个衣服模型、三个头发模型等
  那我们在美术制作的过程中是不是也要这样进行“模型叠加”呢 & 其实没必要
  demo这样的目的是为了使得模型公用一套骨骼 &那么我们在角色模型的制作过程中 &就确保模型使用的是同一套骨骼
  比如男性角色使用一套 &女性角色使用另一套 &当进入创建角色场景后 &根据玩家选择角色的性别 &显示不同的动画即可
4、角色模型打包技巧
  前面提到 &官方demo里换装的实现 &原因是因为公用了一套骨骼 &
  那么我们在打包的时候 &就将骨骼和模型分离 &将模型各个部件(比如头发、手臂等)分开打包 &
  比如一个男性的角色 &将他的基础骨骼打进一个包 & 再将身体各个部分的模型分别打包 &
  如果一个模型由头、脸、身体、手臂、脚五个部分组成 &那么打包后将会有六个资源包 &分别是基础骨骼、头、脸、身体、手臂、脚
  这样游戏的创建角色过程中 &就可以单独地对模型的身体部位进行切换
  打包的过程和官方demo的打包大同小异 &只不过这里作者在打包时捎带生成了换装的配置表
6、角色模型的加载
  unity3d中使用www进行资源的加载 &如果将资源放在了http服务器上的话(包括本机的IIS) &则需要一个crossdomain的xml配置 &本地则不需要
  加载时应该首先去加载基础骨骼 &加载完以后再去加载要显示的默认角色模型 &比如新手模型
  在加载完以后 &则要提取各个模型中所记录的骨骼信息 &根据这些信息将模型挂到对应的骨骼上
  为了避免模型之间出现缝隙 &应当进行模型网格的合并 &
  完成以上工作以后模型的加载就已经实现了
7、角色模型的换装
  回到角色模型打包的话题 &
  设想一个男性角色有10套服装用来更换 &而公用的骨骼是一套 &
  因此在打包时仍然将这一套骨骼单独打包 &然后再将其他所有的模型打包 &
  一句话总结就是 & 一套骨骼对应N个模型 &这N个模型都公用这一套骨骼
  换装的实现实际上就是将相应的身体部分进行更换 &
  比如要换一个手臂 &则将新的手臂与身体上除了手臂以外的模型再进行一次网格合并
  换句话说 &要更换身体某一个部位 &实际上就是更新了整个角色模型
  这里需要注意的一点是 &基础的骨骼不用再去更新 &
  设想一下 &换装时候 &一般角色都会有个“站立”或者“呼吸”的动作在播放 &那么如果同时去更新了一遍基础骨骼 &那么结果势必会让本来连贯的动作有“一闪”的现象
  这是因为 &之前的动画还没播放完 &然后就更新了骨骼 &那么动画又重头开始播 &这之间没有过渡 &肯定会有点问题
控制抗锯齿
设置Edit---ProjectSettings---Quality
我们主要使用3dsmax2010进行制作,输出FBX的类型导入Unity3D中。
默认情况下,3dsmax8可以和U3D软件直接融合,自动转换为FBX物体。
注意事项如下:
1.面数控制
在MAX软件中制作单一GameObject物体的面数不能超过65000个三角形,即32500个多边形Poly,如果超过这个数量的物体不会显示出来,这就需要我们合理分布多边形和模型数量。
打开MAX场景,选择File/Properties/SummaryInfo可以打开文件属性记录。
其中Faces可以看到每个物体的实际数量,个体数量不能超过65000个Faces面。
2.建模控制
Unity3D软件支持Line渲染和编辑之后所产生的模型。大部分模型都依靠Polygon进行制作。在模型表面可以承认多出四边形的面,但不渲染交错的面。
默认情况下,U3D引擎是不承认双面材质的,除非使用植物材质球Nature类型。
所以在制作窗户、护栏等物体,如果想在两面都能看到模型,那需要制作出厚度,或者复制两个面翻转其中一个的Normal法线。
3.文件的放置
模型可以继承MAX的材质,但是文件的设置要按照以下形式进行放
在项目的Assets文件夹内,新创建一个Object文件夹。
并在其中创建Materials和Texture文件夹(分别自动存放材质球和贴图)。
模型物体并列保存在Object文件夹内。
这个规律模式不要打乱,否则会破坏整个系统逻辑。
4.材质数量控制
如果一个物体给与一个材质球,那么Unity3D对于材质数量和贴图数量没有任何的限制。
如果一个物体给与多个材质球,我们需要用Multi/SubObject来实现,但是这种罗列的材质球的数量没有严格的控制,但尽量保持在10以内,过多的数量会导致一些错误。
如果不使用Multi/SubObject材质球,也可以选择一些面,然后给与一个材质球。这样系统会自动将其转换成Multi/SubObject材质。
综合而言Unity3D软件对于材质的兼容还是很好的。
5.物体的质感
Diffuse Bumped
Bumped Specular
这三种类型为常用类型,其中Bumped需要增加Normal法线贴图来实现凹凸。
这种材质为贴花材质,即相当于Mask类型,可以再Decal(RGBA)贴与一个带有Alpha通道的图像,形成和原图像相叠加的效果
Diffuse Detail
这种材质可以创造出污迹和划痕的效果,即相当于Blend混合材质。
Reflective
其中各种类型可以创造出金属反射效果,需要增加Cubmap贴图。
Transparent
其中各种类型可以创造出透明的效果,需要增加具有Alpha的通道贴图。
注意:如果要做玻璃贴图,Alpha如果全是灰色或黑色(即要求全透明),那么Alpha就会失效,如果要全透明,材质Alpha其中必须至少有1像素为白色。
其中SoftOcclusion Leaves类型主要应用于片状的树叶材质。
6.物体尺寸
默认情况下U3D系统单位1等于1米,等于软件1单位。如果我们制作是按照实际大小比例制作,那么导入U3D引擎会自动变成原来的1%的大小。
因为默认情况下,U3D的FBXImporter中的Scale Factor的数值为0.01。
那个我们可以将ScaleFactor的数值恢复为1,但是这样会占用模型资源,比较消耗物理缓存。
我们也可以将这个物体从Hierarchy中选择,并使用Scale放大100倍,这种设置可以有很多好处,并且还能通过用脚本制作动画。
7.关于复制
场景中的灯光布局,重复的模型物体都可以使用系统Prefab进行关联复制,这样可以改变一个参数的同时将所有关联物体属性改变。
8.山脉控制
在创建山脉之后,选择Terrain/Set Resolution可以设置山脉的大小和属性。
需要注意的是,默认情况下TerrainWidth和Terrain Height为1000米。如果设置这个数值太小,那么绘制草的时候会产生偏移,因为草的尺寸必须减少到0.1的单位。
也就是说,山脉在处理0.1单位的时候会产生0.01的偏差,如果模型太小,这种偏差是显而易见的,所以建议用户不要让模型过小。
9.光晕控制
光晕又称为Lens Flare即灯光光效。
可以选择一个GameObject物体给与Component/Rendering/LensFlare,并在Flare中增加一个StandardAssets/Light Flares/50mm Zoom项目。这样在运行之后就会产生光晕。
但有时候如果光晕太远太高却看不到。
一种办法是将光晕离近,另一种办法是将所有摄影机Camera的Far clip plane的数值增加。
10.摄影机控制
如果场景中有多架摄影机,那么如何确定第一打开时间所显示的摄影机,就需要设置Camera属性中的Depth数值,数值越大的摄影机越优先显示。
下面给你提供写方法以剥离减小包的大小,有些我也没试过:
降低的播放机大小主要有两个途径:一是更改Xcode内的Active Build Configuration,二是更改Unity的Stripping级别。
在发布模式下生成
你可以在 Xcode的Active Build Configuration下拉菜单中的调试和发布选项之间进行选择。根据自身游戏的大小,选择发布模式生成的player会比选择调试模式减少2-3MB的大小。
在发布模式下,player会去掉任何的调试信息进行生成,所以如果你的游戏崩溃或有其他问题,将是没有可用的、可输出的堆栈跟踪信息。这适合发布已完成的游戏,但你更应该在开发过程中使用调试模式。
iOS Stripping级别(Advanced License feature)
尺寸优化工作可通过以下几种方式被剥离机制激活:
Strip assemblies级别:通过分析脚本的字节码,来将这些脚本没有引用的类和方法从 Dll 中删除,从而使其不进入 AOT编译阶段。这种优化减少了主要的二进制以及相应 Dll的大小。在不使用反射的条件下,这种优化是安全的。
Strip ByteCode级别:任何.Net Dll(存储数据文件夹中)将从元数据中被剥离出来。这是可能的,因为所有的代码都已经 AOT阶段被预编译并链接到主要的二进制文件中
使用micro mscorlib级别:使用一种特殊的、较小的mscorlib版本。某些部件将从此库中被移除,例如,安全,Reflection.Emit,远程处理,非公历日历等组件都将被删除。此外,内部组件之间的相互依赖性也会被降至最低。该种优化减少了主要的二进制以及mscorlib.dll的大小,但不能与一些系统和 System.Xml程序集类兼容。因此,小心地使用它。
这些级别是累积的,第3级优化隐式地包含级别 2和级别1,而第 2级优化则包含级别1。
Micro mscorlib是核心库的最低级版本。只有这些项目是目前Unity中的Mono运行库所需要的。使用micro mscorlib的最佳做法是不使用任何你的应用程序所不需要的.Net的类或其他功能。GUID就是一个你可以忽略的例子,她可以轻松地被自定义的伪 Guid所替代,这样做将产生更好的性能和更小的应用程序。
如何处理使用反射机制的Strip
Strip程度取决于静态代码的分析,但有时侯,这种分析并不是很有效,特别是针对使用类似反射一样的动态功能的代码。在这种情况下,有必要给出一些提示来指出哪些类是不应该被触动的。Unity支持对于每个项目都给出一个自定义Strip黑名单。使用黑名单是创建 link.xml 文件并将它放入Assets文件夹的一个简单方法。以下是一个的 link.xml文件的示例。其中有保留标记的类将不会被Strip:
有时侯,我们很难确定哪些类会被进行错误的Strip。通常你可以通过在模拟器上运行已被Strip的应用程序和检查 Xcode 控制台的错误消息来获取有用的信息。
简单的清单,使你的发布版本尽可能地小
1.最小化你的资源(assets):启用 PVRTC压缩纹理,并尽可能低降低其分辨率。此外,尽量缩减无损压缩的音频的个数。这里还有一些额外的缩减文件大小的提示。
2.设置iOSStrip级别为Use micro mscorlib。
3.设置脚本调用优化级别为Fast but no exceptions。
4.不要让你的任何代码与System.dll或 System.Xml.dll有关联,因为这些库并不兼容micro mscorlib。
5.去掉不必要的代码关联。
6.将API兼容性级别设置为.Net 2.0子集。请注意.Net 2.0子集与其他库与兼容性比较有限。
7.设置目标平台为armv6 (OpenGL ES1.1)。
8.不要使用 JS阵列。
9.避免泛型容器与结构等类型相结合。
我能用Unity创造出低于 20 mb的应用程序吗?
当然可以。如果所有优化被都关掉,一个空项目在AppStore中大小大致为 13 MB左右。这在游戏中为你提供了大约7 MB的压缩资源预算。如果你拥有先进的许可证(并因此获得Strip选项),那么只含有主相机的空场景在AppStore中可压缩到大约 6 MB (zipped和 DRM连接),这样,你就可以有大约 14 MB可用空间用于压缩资源。
为什么我的应用程序发布到AppStore后大小增加了?
当他们发布你的应用程序时,苹果首先对二进制文件进行加密,然后将它通过 zip压缩。最常见的,苹果 DRM会使二进制文件大小增加大约 4 MB左右。作为一般规则,你应预见到的文件最终大小大致为所有文件(除了可执行文件)的 zip压缩大小,再加上未压缩的可执行文件的大小。
boxcollider或者其他任何collider 都是为物理碰撞或者碰撞检测做准备。
刚体属性组件,在任何物体下的Add component (添加零件、添加组件)可添加。
物体勾了tigger 那个属性,或者是地面勾了那个属性。tigger是能进入内部的,通常做判断触发范围
------------------------------------------
通常在变换场景后,上个场景中除了使用 DontDestroyOnLoad() 保留的物件,将会被释放掉,但如果在没有变换场景的情形下,想把未使用的资源卸载掉,该如何做呢?
一般情况下,我们会利用 Unity 的编辑器来部属每个关卡或场景中的物件,这些物件在载入场景后都是必要的,也不太会持续增加物件数,在关卡结束后即转换到下个场景,所以原本场景中的物件 将不再需要,所以 Unity 将会自动将前一场景的物件都销毁掉,所以我们通常不太需要去管理记忆体的使用或是否释放,但如果你的游戏全部是在单一个场景中运行的,那麼物件的產生、销 毁、释放资源等等的动作就变得格外重要。
我做了一个宝石类型的游戏,画面上除了 GUI 及背景外就只有宝石,所以我事先将宝石做成 Prefabs ,在需要时利用 Instantiate() 產生,我在不同的关卡利用 renderer.material.mainTexture 变更背景图,利用 GetComponent(MeshFilter).sharedMesh 变更宝石的形状以及利用 renderer.material.color 变更宝石顏色,如此一个Prefabs 可以重复无限使用,所以在游戏场景中只设置了简单几个场景物件,在这种场景不需要变化太多的情况下,每个关卡都换场景重新配置一样的物件似乎有点多餘,所
以这个游戏便只有一个场景,在需要时產生宝石,然后再视情况使用 Destroy() 销毁掉,这样看起来只要在產生宝石时控制画面上的物件数量,那麼也就不用担心记忆体使用过量或没释放掉的问题。
但是,这个游戏在连续玩好几个关卡后,也就是连续玩一段时间后,会发生停顿或画面变慢的问题,游戏刚开始玩时是相当顺畅的,但长时间执行将使效能降低,直 觉上的判断应该是记忆体累积到一定程度造成的,每个物件在不使用时都使用 Destroy() 销毁掉,那麼,堆积的记忆体是从哪裡来的呢?
打开 Profiler 视窗看看,会发现其中的 Memory 的 Total Object Count 数值,不断的增减变化,但随着时间的增加会慢慢的往上累积,查看官网 (/support/documentation/Manual/Profiler.html) 是这样说的 &If this number rises over time then it means your game is creating some objects that are never destroyed.&,有些物件未销燬,很奇怪吧!都有使用
Destroy(),那為何还有未销毁的物件?其实,主要是因為我这裡有对 renderer.material 设置改变其内容,在这个执行时期并不会真的去改变 Project 中的 material,而是產生这个物件实例(instance) 的材质实例以供该物件使用,所以如果只是 Destroy(gameObject) 的话,将会残留部份物件数,每个產生的物件都残留一点点的话,慢慢的长时间下来将会累积相当多,记忆体将会不敷使用,所以在 Destroy(gameObject) 的同时,应该也要 Destroy(renderer.material)
如果程式结构简单,给物件使用的 Script 档案也不多的话,也许多加一句并不困难,但我们有时候无法确定是否有在适当时机為每个物件做到完整的销毁,也许还有残留别的东西也会有这种情形持续累积记 忆体,这时又该寻找更简单统一的方法了,於是我们可以在每个关卡开始前或结束时执行一句 Resources.UnloadUnusedAssets() ,让 Unity 自行去卸载掉不使用的资源,如此在平时物件销毁时,我们已经先行释放掉大部份不使用的资源,然后再由 Resources.UnloadUnusedAssets()
卸载我们未清理掉的部份,如此的话查看 Profiler 视窗的 Memory 的 Total Object Count 数值就可以维持在一定范围内起伏,而不再随着时间增加,当然我们在关卡设置上都会有难度上的差异,在某些关卡裡,玩家可能必须花较多时间才能完成关卡,所 以如果我们只在关卡开始或结束时使用 Resources.UnloadUnusedAssets() 也许会不够,此时也可另外定义每过一段时间就执行 Resources.UnloadUnusedAssets() ,如此将可避免掉系统资源不足的问题。&
.cn/s/blog_6af6af4b0100yy7n.html
在做项目过程中,经常会遇到一种情况:
场景中有不同种类的实例对象,这些实例可以是不同的3D物体。当我们需要点击其中一个物体(GameObject)时,希望他能够自动删除自己,并且将也要把对应的数组记录删除,保证数据统一。要实现以上所说的,需要建立一种自调用方法来实现。/unity3d-destroy-gameobject.html
相关搜索:
相关阅读:
相关频道:
Android教程最近更新

我要回帖

更多关于 3d打印机为什么不普及 的文章

 

随机推荐