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.position; }

可改为

private var pos: Vector3; function Update(){ pos = transform.position; }

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 等等

降低固定增量时间

将固定增量时间值设定在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 blocks

for (var i : int = 0; i < 1024; i++)

tmp[i] = new byte[1024];

// release reference

tmp = null;

}

游戏中的暂停是用来对堆内存进行回收。而一个足够大的堆应该不会在游戏的暂停与暂停之间被全然占满。所以。当这样的游戏暂停发生时。您能够显式请求一次垃圾回收:

System.GC.Collect();

另外,您应该慎重地使用这一策略并时刻关注Profiler的统计结果,而不是假定它已经达到了您想要的效果。

原文链接:http://blog.sina.com.cn/s/blog_6ad33d35010136fl.html

Unity3D 移动开发代码优化的更多相关文章

  1. Unity3D游戏开发初探—1.跨平台的游戏引擎让.NET程序员新生

    一.Unity3D平台简介 Unity是由Unity Technologies开发的一个让轻松创建诸如三维视频游戏.建筑可视化.实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的 ...

  2. Unity3D游戏开发初探—2.初步了解3D模型基础

    一.什么是3D模型? 1.1 3D模型概述 简而言之,3D模型就是三维的.立体的模型,D是英文Dimensions的缩写. 3D模型也可以说是用3Ds MAX建造的立体模型,包括各种建筑.人物.植被. ...

  3. 从一点儿不会开始——Unity3D游戏开发学习(一)

    一些废话 我是一个windows phone.windows 8的忠实粉丝,也是一个开发者,开发数个windows phone应用和两个windows 8应用.对开发游戏一直抱有强烈兴趣和愿望,但奈何 ...

  4. Unity3D游戏开发之连续滚动背景

    Unity3D游戏开发之连续滚动背景 原文  http://blog.csdn.net/qinyuanpei/article/details/22983421 在诸如天天跑酷等2D游戏中,因为游戏须要 ...

  5. Unity3D游戏开发从零单排(四) - 制作一个iOS游戏

    提要 此篇是一个国外教程的翻译,尽管有点老,可是适合新手入门. 自己去写代码.debug,布置场景,能够收获到非常多.游戏邦上已经有前面两部分的译文,这里翻译的是游戏的最后一个部分. 欢迎回来 在第一 ...

  6. [Unity3D]Unity3D游戏开发之飞机大战项目解说

    大家好,我是秦元培,欢迎大家继续关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei. 首先感谢大家对我博客的关注,今天我想和大家分享的是一个飞机大战的项目.这是一个比較综合的 ...

  7. [Unity3D]Unity3D游戏开发《反对》说到游戏(上)——目标跟踪

    朋友,大家好.我是秦培,欢迎关注我的博客.我的博客地址blog.csdn.net/qinyuanpei. 首先博主要自我反省,过了这么久才来更新博客,这段时间主要是在忙着写期末的作业,所以博主基本上没 ...

  8. [Unity3D]Unity3D游戏开发3D选择场景中的对象,并显示轮廓效果强化版

    大家好,我是秦培,欢迎关注我的博客,我的博客地址blog.csdn.net/qinyuanpei. 在上一篇文章中,我们通过自己定义着色器实现了一个简单的在3D游戏中选取.显示物体轮廓的实例. 在文章 ...

  9. [Unity3D]Unity3D游戏开发之跑酷游戏项目解说

    大家好,我是秦元培.我參加了CSDN2014博客之星的评选,欢迎大家为我投票,同一时候希望在新的一年里大家能继续支持我的博客. 大家晚上好.我是秦元培,欢迎大家关注我的博客,我的博客地址是blog.c ...

随机推荐

  1. 专访阿里巴巴研究员“赵海平”:Facebook的PHP底层性能优化之路(HipHop,HHVM)

    专访阿里巴巴研究员“赵海平”:Facebook的PHP底层性能优化之路 http://www.infoq.com/cn/articles/interview-alibaba-zhaohaiping

  2. JavaScript字符串api简单说明

    1.可返回指定位置的字符 stringObject.charAt(index); 2.返回的是位于指定位置的字符的编码 stringObject.charCodeAt(index); 3.用于连接两个 ...

  3. linux/mac系统的软链接文件与硬链接文件

    1.硬连接只能使用在文件上,不可以使用在文件夹上.至于文件前面的硬链接数字的含义如下: 如图标注区,为硬连接的数量,文件前的数字1表示没有硬链接.文件夹前面的数字至少是2,含义是这个文件夹是空文件夹, ...

  4. linux基础-第十八单元_nginx部署

    一.基本环境配置 1.1.安装常用软件 yum install wget -y 1.2.Install yum repo mv /etc/yum.repos.d/CentOS-Base.repo /e ...

  5. How Tomcat Works 读书笔记 八 加载器 上

    Java的类加载器 具体资料见 http://blog.csdn.net/dlf123321/article/details/39957175 http://blog.csdn.net/dlf1233 ...

  6. kubelet分析

    kubelet是k8s中节点上运行的管理工具,它负责接受api-server发送的调度请求,在Node上创建管理pod,并且向api-server同步节点的状态.这篇文章主要讲讲kubelet组件如何 ...

  7. 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-人机界面如何设置页面跳转

    TC3中,可以点击某个按钮,改变所显示的视图,然后从你写好的页面中选择一个要跳过去的页面   当然,在跳过去的页面上再做一个按钮可以跳回主页面也是必须的     更多教学视频和资料下载,欢迎关注以下信 ...

  8. Office如何加密解密

    1 任意打开一个EXCEL文档,并点击工具,选项,切换到安全性选项卡,任意设置密码   设置密码保护之后再次打开就需要输入密码 我们使用该软件Office PassWord Remover打开该文档( ...

  9. 你是那种仅仅看《XXXXX从入门到精通》的程序猿吗?

    我一開始又要废话一番了. 实际上上了大学以后.你常常会在网上,在和别人的交流里,在老师的课堂上.反复听到一些书,比方黄仁宇的<万历十五年>.王小波"时代三部曲".村上春 ...

  10. Excel中如何将时间戳转为时间?

    Unix时间戳转换Excel时间? Excel中如何将时间戳转为时间? Excel默认不支持Unix格式时间戳,这在导入数据时十分不便.可以用以下公式将时间戳转换成Excel格式的时间: =(x+8* ...