博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Unity 的一些优化总结 (难度3 推荐4)
阅读量:5168 次
发布时间:2019-06-13

本文共 2849 字,大约阅读时间需要 9 分钟。

原文地址:

http://www.jianshu.com/p/3acee1101fe4

从别的地方看到一些资源使用方面的文章,从中抽取一些细节在这里总结一下:

Draw Call数量、Triangle数量 和 可见蒙皮网格数量

一般来说,Draw Call 数量、Triangle 数量 和 可见蒙皮网格数量 的推荐值需根据平台的不同而不同。对于 Mobile 低端移动设备来说,建议 Draw Call 数量的主要范围在 [0,200] 区间内,Triangle 数量保持在 10万 以下,可见蒙皮网格数量保持在 50 以下。

Contacts 数量、Rigidbody 数量 和 碰撞体数量

Contacts 数量为碰撞对(Contact Pair)数量。所谓“碰撞对”,是指当前空间中发生碰撞的物体之间的接触点,每个 “碰撞对” 均连接两个相互产生碰撞的物体。一般来说,Contacts 数量越大,则表明碰撞物体的数量越多,即物理系统的CPU开销越大。

Rigidibody数量 和 碰撞体数量, 其标准值需因运行平台的不同而不同。对于Mobile移动设备来说,建议 Rigidibody数量 控制在 50 以下,碰撞体数量(静态碰撞体和动态碰撞体) 控制在 100 以下。

贴图资源

在纹理资源的优化方面,建议尽可能降低其内存上的占用,其主要影响因素包括纹理分辨率、纹理格式、Mipmap等。对于纹理格式,则尽可能采用适合于发布平台的硬件支持纹理格式,比如对于Android平台,建议使用ETC1格式,对于iOS平台,建议使用PVRTC格式,对于PC,建议使用DXT格式等等。

注意:在Android平台上,ETC1格式不支持半透明纹理,所以半透明纹理可以直接转换成RGBA16格式进行渲染。当然,更为出色的办法是,将半透明纹理拆分成两张纹理,记录RGB通道信息的RGB24格式纹理和记录Alpha通道信息的Alpha8格式纹理,然后再分别转成ETC1格式进行保存。这种方法既可以最大限度地保证渲染质量,又可以极大降低纹理内存的占用。

纹理从RGBA32转换成RGBA16、ETC1或PVRTC格式时,均会带来一定程度的质量损失,甚至出现难以接受的 “色阶” 效果。究其原因,是因为纹理图像中的过渡色所致。因此,建议您在显示效果和性能效率方面进行权衡,尽可能降低过渡色的跨度范围

“多余” 数据的危害还体现在网格拼合上。Unity 引擎的 Draw Call Batching 功能或您自己调用的 StaticBatchingUtility API 均可以将场景中的网格数据进行拼合,从而形成一个或几个较大的 VBO(Combined Mesh)。这种做法是渲染优化时的常见方法,主要用于降低渲染模块的Draw Call数量,从而提升渲染效率。这本身是一个非常棒的功能,但您需要注意的是,网格合并时一定要保证网格数据结构的统一性,否则会大大增加拼合网格(Combined Mesh)的数据量!举个例子,当拼合100个网格模型时,如果99个模型网格数据中仅含有Vertex、UV等数据,而仅有1个模型网格数据中含有Vertex、UV、Normal、Color和Tangent数据,则拼合后,拼合网格中的所有顶点均会添加上 Normal、Color 和 Tangent 数据,大量的 “多余” 数据也就由此产生了...

总内存和使用内存

Reserved Total 和 Used Total 为Unity引擎在内存方面的总体分配量和总体使用量。 一般来说,引擎在分配内存时并不是向操作系统 “即拿即用”,而是首先获取一定量的连续内存,然后供自己内部使用,待空余内存不够时,引擎才会向系统再次申请一定量的连续内存进行使用。Reserved Total 的内存占用量略大于 Used Total, 且两者走势基本一致。

注意:对于绝大多数平台而言,Reseved Total内存 = Reserved Unity内存 + GFX内存 + FMOD内存 + Mono内存

通过针对大量项目的深度分析,我们发现导致 Reserved Unity 内存分配较大的原因主要有以下几种:

  1. WebStream内存占用:WebStream为项目通过特定API(WWW、CreateFormMemory等)加载AssetBundle文件所开辟的较大块内存。主要用于存放AssetBundle的原始数据和解压后数据。
  2. 序列化信息内存占用:Unity引擎的序列化信息种类繁多,其中最为常见且内存占用较大的为SerializedFile。该序列化信息的内存分配主要为项目通过特定API(WWW.LoadFromCacheOrDownload、CreateFromFile等)加载AssetBundle文件所致。
  3. 资源内存占用:主要包括Mesh、AnimationClip、RenderTexture等资源。在默认情况下,当FBX模型导入时,其 “Read/Write Enable” 选项是默认开启的,即其Mesh网格数据会在 Reserved Unity 中保留一份,便于项目在运行时对Mesh数据进行实时的编辑和修改。同时,如果研发团队同样开启了纹理资源的 “Read/Write Enable” 选项(默认情况下为关闭),则纹理资源同样会在 Reserved Unity 中保留一份,进而造成其更大的内存占用。

GFX内存 为底层显卡驱动所反馈的内存分配量,该内存分配由底层显卡驱动所控制。一般来说,该部分内存占用主要由渲染相关的资源量所决定,包括纹理资源、Mesh资源、Shader资源以及解析这些资源的相关库所分配的内存等。

托管堆内存 表示项目运行时代码分配的托管堆内存分配量。对于使用Mono进行代码编译的项目,其托管堆内存主要由Mono分配和管理;对于使用IL2CPP进行代码编译的项目,其托管堆内存主要由Unity自身分配和管理。目前,除iOS平台外,其他平台的绝大多数项目还在使用Mono来进行代码编译。

对于Mono堆内存来说,由于Mono自身的限制,其堆内存分配是 “只升不降” 的,即内存一旦分配给Mono,不论以后该内存是否继续被使用,都不会再归还给系统。因此,建议您对于代码的堆内存分配进行严格的控制,避免不必要的Mono堆内存分配。

Instantiate实例化操作

一般情况下,我们不建议项目在运行过程中频繁地调用 Instantiate 和 Destroy 来创建和销毁一个GameObject。这种做法不仅可能会造成频繁且较高的CPU占用,更重要的是,它将造成大量的内存碎片,从而造成越来越多的堆内存分配,进而加速系统垃圾回收操作(Garbage Collection)的到来

转载于:https://www.cnblogs.com/4unity3d/p/6848403.html

你可能感兴趣的文章
数据结构(c语言版)代码
查看>>
Linux入门-网络实验3.3
查看>>
php中$_ENV为空解决办法
查看>>
第二十四节(Java文件流,缓冲流)
查看>>
正则表达式
查看>>
Android SurfaceView详解
查看>>
比赛排名
查看>>
phpcms v9框架的目录结构分析
查看>>
如何从右键弹出菜单中清空删除数据加清空前提问确定
查看>>
Python将某文件夹及其子文件夹下某种格式的文件移动到另一个指定的文件下
查看>>
ubuntu18.04新体验
查看>>
mysql每次update数据,自动更新对应表中时间字段
查看>>
cocos2d-x关于CCTableView的“乱序问题”的理解
查看>>
[置顶] 63行代码完美实现html5 贪吃蛇游戏
查看>>
AppDelegate
查看>>
Delphi 中的 procedure of object
查看>>
sublime ctrl b突然不能用解决方法
查看>>
查看端口占用情况
查看>>
jzoj5878
查看>>
fft模板
查看>>