Unity3D教程:ISO系统性能与脚本的优化
来源:互联网 发布:侯赛因国王知乎 编辑:程序博客网 时间:2024/06/17 08:44
Unity3D教程手册
Unity3DISO系统性能与脚本的优化
减少固定增量时间
将固定增量时间值设定在0.04-0.067区间(即,每秒15-25帧)。可以通过Edit->Project Settings->Time来改变这个值。这样做降低了FixedUpdate函数被调用的频率以及物理引擎执行碰撞检测与刚体更新的频率。如果使用了较低的固定增量时间,并且在主角身上使用了刚体部件,那么可以启用插值办法来平滑刚体组件。
减少GetComponent的调用
使用 GetComponent或内置组件访问器会产生明显的开销。可以通过一次获取组件的引用来避免开销,并将该引用分配给一个变量(有时称为"缓存"的引用)。例如,代码如下:
function Update () {transform.Translate(0, 1, 0);}
通过下面的更改您将获得更好的性能:
var myTransform : Transform;function Awake () {myTransform = transform;}function Update () {myTransform.Translate(0, 1, 0);}
避免分配内存
应避免分配新对象,除非你真的需要,因为他们不再在使用时,会增加垃圾回收系统的开销。可以经常重复使用数组和其他对象,而不是分配新的数组或对象。这样做好处则是尽量减少垃圾的回收工作。同时,在某些可能的情况下,也可以使用结构(struct)来代替类(class)。这是因为,结构变量主要存放在栈区而非堆区。因为栈的分配较快,并且不调用垃圾回收操作,所以当结构变量比较小时可以提升程序的运行性能。但是当结构体较大时,虽然它仍可避免分配/回收的开销,而它由于"传值"操作也会导致单独的开销,实际上它可能比等效对象类的效率还要低。
最小化GUI
使用GUILayout 函数可以很方便地将GUI元素进行自动布局。然而,这种自动化自然也附带着一定的处理开销。可以通过手动的GUI功能布局来避免这种开销。此外,也可以设置一个脚本的useGUILayout变量为 false来完全禁用GUI布局:
function Awake () {useGUILayout = false;}
使用iOS脚本调用优化功能
UnityEngine 命名空间中的函数的大多数是在 C/c + +中实现的。从Mono的脚本调用 C/C++函数也存在着一定的性能开销。可以使用iOS脚本调用优化功能(菜单:Edit->Project Settings->Player)让每帧节省1-4毫秒。此设置的选项有:
Slow and Safe – Mono内部默认的处理异常的调用
Fast and Exceptions Unsupported –一个快速执行的Mono内部调用。不过,它并不支持异常,因此应谨慎使用。它对于不需要显式地处理异常(也不需要对异常进行处理)的应用程序来说,是一个理想的候选项。
优化垃圾回收
如上文所述,应该尽量避免分配操作。但是,考虑到它们是不能完全杜绝的,所以我们提供两种方法来让您尽量减少它们在游戏运行时的使用:如果堆比较小,则进行快速而频繁的垃圾回收。
这一策略比较适合运行时间较长的游戏,其中帧率是否平滑过渡是主要的考虑因素。像这样的游戏通常会频繁地分配小块内存,但这些小块内存只是暂时地被使用。如果在iOS系统上使用该策略,那么一个典型的堆大小是大约 200 KB,这样在iPhone 3G设备上,垃圾回收操作将耗时大约 5毫秒。如果堆大小增加到1 MB时,该回收操作将耗时大约 7ms。因此,在普通帧的间隔期进行垃圾回收有时候是一个不错的选择。通常,这种做法会让回收操作执行的更加频繁(有些回收操作并不是严格必须进行的),但它们可以快速处理并且对游戏的影响很小:
if (Time.frameCount % 30 == 0){System.GC.Collect();}
但是,应该小心地使用这种技术,并且通过检查Profiler来确保这种操作确实可以降低您游戏的垃圾回收时间。
如果堆比较大,则进行缓慢且不频繁的垃圾回收。这一策略适合于那些内存分配 (和回收)相对不频繁,并且可以在游戏停顿期间进行处理的游戏。如果堆足够大,但还没有大到被系统关掉的话,这种方法是比较适用的。但是,Mono运行时会尽可能地避免堆的自动扩大。因此,您需要通过在启动过程中预分配一些空间来手动扩展堆(ie,你实例化一个纯粹影响内存管理器分配的"无用"对象):
function Start() {var tmp = new System.Object[1024];// make allocations in smaller blocks to avoid them to be treated in a special way, which is designed for large blocksfor (var i : int = 0; i < 1024; i++)tmp[i] = new byte[1024];// release referencetmp = null;}
游戏中的暂停是用来对堆内存进行回收,而一个足够大的堆应该不会在游戏的暂停与暂停之间被完全占满。所以,当这种游戏暂停发生时,可以显式请求一次垃圾回收:
System.GC.Collect();
另外,应谨慎地使用这一策略并时刻关注Profiler的统计结果,而不是假定它已经达到了想要的效果。
Unity3D教程手册http://www.unitymanual.com/
- Unity3D教程:ISO系统性能与脚本的优化
- unity3d 性能 脚本优化
- Unity3D教程:性能优化
- Unity3D的优化性能
- unity3d的性能优化
- Unity3D教程:常规性能优化技巧
- Unity3D通用的性能优化
- unity3d移动平台性能优化专题(11):脚本细节
- 优化JavaScript脚本的性能
- javascript脚本的性能优化
- Unity3D性能优化 - Update() 的使用
- Unity3D性能优化--- 收集整理的一堆
- Unity3D性能优化--- 收集整理的一堆
- Unity3D性能优化--- 收集整理的一堆
- 【Unity3D性能优化】ParticleSyetem的alive (一)
- Unity3D性能优化 - Update() 的使用
- Unity3D性能优化--- 收集整理的一堆
- Unity3D性能优化--- 收集整理的一堆
- HDU 2037 今年暑假不AC
- POJ 2398 Toy Storage
- C/C++内存管理详解
- zoj 3175 Number of Containers (nbut1375) 计算n /1+n/2+n/3+n/4....+n/n
- 位图引起的内存溢出OutOfMemory解决方案
- Unity3D教程:ISO系统性能与脚本的优化
- 想创业开公司?你需要这9种特质
- 对话框窗口过程与普通窗口过程的区别
- POJ 3067 Japan
- IAR编译ZStack-CC2530,生成HEX文件完全配置
- U盘不识别,磁盘管理器显示无媒体
- CentOS SSH配置
- AUL/MyDUL修复Oracle
- 客户的报表第一行的高度超过一张A4纸的高度的解决办法