查看: 1449|回复: 0
打印 上一主题 下一主题

Unity3d_性能优化

[复制链接]

435

主题

2

听众

6371

积分

高级设计师

Rank: 6Rank: 6

纳金币
6372
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2012-9-12 10:52:05 |只看该作者 |倒序浏览

1.使用静态类型
当使用JavaScript很重要的优化是使用静态类型替代动态类型。Unity使用一种技术叫做类型推理的技术来自动转换JavaScript为静态类型脚本。
var foo = 5;
上面例子中的foo将自动被推断为一个整数值。因此,Unity可能使用大量的编辑时间进行优化,而不使用耗时的动态名称变量查找等。这就是为什么Unity的JavaScript执行平均速度是其他JavaScript的20倍的原因之一。
唯一的问题是有时不是所有的东西都能做类型推断,Unity将会为这些变量重新使用动态类型。通过这样,编写JavaScript代码很简单,但也会使代码运行速度变慢。
看个例子:
function Start ()

{

    var foo = GetComponent(MyScript);

    foo.DoSomething();

}
这里foo将是动态类型,因此呼叫函数DoSomething必须要较长的时间,因为foo的类型未知,它必须弄明白是否支持DoSomething函数,如果支持,调用函数。
function Start ()

{

    var foo : MyScript = GetComponent(MyScript);

    foo.DoSomething();

}
这里我们强制foo为指定类型,你将获得更好的性能。
2.使用#pragma strict
现 在问题是,你通常不会意识到你在使用动态类型。#pragma strict可以解决这个问题!简单的添加#pragma strict在脚本顶部,之后Unity将禁用脚本的动态类型,强制你使用静态类型。如果有一个类型未知,Unity将报告编译错误。下面,foo将在编 译时报错:
#pragma strict

function Start ()

{

    var foo = GetComponent(MyScript);

    foo.DoSomething();

}
3.缓存组件查找
另一个优化是组件缓存。这种优化需要一些代码并且不是总有必要。但是如果你的代码真的很大,并且你需要尽可能的性能提升,它会是很好的优化。
当你通过GetComponent获取一个组件或一个变量时,Unity必须从游戏物体里找到正确的组件。这时你便能通过一个缓存组件引用到一个私有变量。
将:
function Update () {

    transform.Translate(0, 0, 5);

}
转换为:
private var myTransform : Transform;

function Awake () {

    myTransform = transform;

}



function Update () {

    myTransform.Translate(0, 0, 5);

}
后面的代码运行较快,因为Unity不用在每一帧寻找变换组件。同样,支持脚本组件。你可以使用GetComponent获取组件或其他快捷属性。
4.使用内置数组
内 置数组是非常快的。ArrayList或Array类很容易使用,你能轻易添加元件。但是他们有完全不同的速度。 内置数组有固定长度,并且大多时候你会事先知道最大长度然后填充它。内置数组最好的一点是他们直接嵌入结构数据类型在一个紧密的缓存里,而不需要任何额外 类型信息或其他开销。因此,在缓存中遍历它是非常容易的,因为每个元素都是对齐的。
private var positions : Vector3[];

function Awake () {

    positions = new Vector3[100];

    for (var i=0;i<100;i++)

    positions = Vector3.zero;

}
5.如果没有必要不要调用函数
最简单,最好的优化是执行最少的工作。如,当一个敌人在远处时,让他处于睡眠状态,大多时候是可行的。直到玩家靠近,可以这样处理:
function Update ()

{

// Early out if the player is too far away.

    if (Vector3.Distance(transform.position, target.position) > 100)

    return;

    perform real work work...

}
这 并不是很好的方法,虽然Unity不得不在每一帧访问update函数。更好的方法是禁用这个行为直到玩家靠近。有3中方法做这个:使用 OnBecameVisible和OnBecameInvisible。这些调用与渲染系统相联系。一旦摄像机看到物体,OnBecameVisible 将被调用,不看他时,OnBecameInvisible被调用。这有时很有用。但是对于AI来讲通常是没有用的,因为你背转敌人,敌人就变成不可用了。
function OnBecameVisible () {

    enabled = ***e;

}



function OnBecameInvisible ()

{

    enabled = false;

}
2.使用触发器。一个简单的球形触发器能引发惊人效果。你可以调用OnTriggerEnter/Exit,当进入你想要的作用范围。
function OnTriggerEnter (c : Collider)

{

    if (c.CompareTag("layer"))

    enabled = ***e;

}



function OnTriggerExit (c : Collider)

{

    if (c.CompareTag("layer"))

    enabled = false;

}
3.使用协同程序。Update的问题是他在每帧都发生。很可能只需要5秒钟检查一次玩家的距离。这可以节约大量的处理周期。
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-12-1 05:05 , Processed in 0.091740 second(s), 33 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部