unity 3d 优化

二.如何优化内存?

有很多种方式,例如

1.压缩自带类库;

2.将暂时不用的以后还需要使用的物体隐藏起来而不是直接Destroy掉;

3.释放AssetBundle占用的资源;

4.降低模型的片面数,降低模型的骨骼数量,降低贴图的大小;

5.使用光照贴图,使用多层次细节(LOD),使用着色器(Shader),使用预设(Prefab)。


1、模型

(1)合并模型,渲染静态窗口比较有用。
(2)100个三角形的MESH,在渲染时与1500个面数的物体是没太大差别的,所以最佳的渲染设置应该在每个模型大约1500-4000个三角面。
(3)一个Mesh 一个材质(按材质合并)。
(4)合并时可以将灯光附近的物体合并,加快渲染。

(5)实时灯光数量限制。

2、实时灯光
  (1)每个被灯光照射到的GameObject都会在每一帧被渲染一次。经常被灯光照射的物体最好合并他。以免多次渲染。
  (2)每一个灯光都会有一个Render Mode设置,Force Pixel 或者 Force Vertex。
  夜晚打开车灯,前面的车灯就是游戏中最重要的灯光。因此,前大灯的渲染模式将会被设置为Force Pixel比较好。
  如果灯光不是很重要,就可以选用"Force Vertex"的渲染模式。
3、阴影
阴影运算量比较大。如果不是做光照分析建议使用 Lighting Map。
4、角色建模优化
(1)角色应该只被用于一个蒙皮模型渲染器。当然有时候可能需要多个蒙皮的模型,但是如果你同时用两个蒙皮来作为一个角色,它就相当于你进行了两个角色的运算量。
(2)要保持MESH的材质数量尽可能低。一般建议身体的材质数量为2-3个,当然如果你有武器的材质,也是需要单独一个的,因为你需要换武器。
(3)一般来说游戏中的骨骼数量为15-60个。骨骼越少运行速度越快,一般来说30块骨骼就可以让角色动的很舒服了。如果你不是有特殊的设置,强烈建议每个角色30个骨骼。
(4)面数主要是看游戏的质量要求,500-6000个三角面是比较推荐的。如果你的游戏场景中将会出现多个角色,那么就要适当的减面。如果你想要在比较老的机器上运行,需要更少的面。比如,半条命2游戏的角色通常是2500-5000个三角面。达到AAA标准的次时代游戏比如像是PS3或者XBOX360上的游戏角色通常有5000-7000个三角面。(5)把IK控制器和FK控制器分离,当动画导入以后,IK的节点将会烘焙到FK上,其实UNITY并不需要IK节点,你可以删除它们。
(6)创建一个公共的骨架,这样就可以让你让不同的角色之间共享动作了。
(7)给每一个骨骼正确的命名,方便团队工作,也方便类似于Motionbuilder的动作软件,不然你得每次指定骨骼。
8)UV接缝的数量尽可能少

5、脚本优化
(1)使用静态类型
当使用JavaScript很重要的优化是使用静态类型替代动态类型。Unity使用一种技术叫做类型推理的技术来自动转换JavaScript为静态类型脚本。
var foo = 5;
上面例子中的foo将自动被推断为一个整数值。因此,Unity可能使用大量的编辑时间进行优化,而不使用耗时的动态名称变量查找等。这就是为什么Unity的JavaScript执行平均速度是其他JavaScript的20倍的原因之一。
唯一的问题是有时不是所有的东西都能做类型推断,Unity将会为这些变量重新使用动态类型。通过这样,编写JavaScript代码很简单,但也会使代码运行速度变慢。
看个例子:
functionStart (){    var foo = GetComponent(MyScript);   foo.DoSomething();}
这里foo将是动态类型,因此呼叫函数DoSomething必须要较长的时间,因为foo的类型未知,它必须弄明白是否支持DoSomething函数,如果支持,调用函数。
functionStart (){    var foo : MyScript =GetComponent(MyScript);    foo.DoSomething();}
这里我们强制foo为指定类型,你将获得更好的性能。
(2)使用#pragma strict
现在问题是,你通常不会意识到你在使用动态类型。#pragma strict可以解决这个问题!简单的添加#pragma strict在脚本顶部,之后Unity将禁用脚本的动态类型,强制你使用静态类型。如果有一个类型未知,Unity将报告编译错误。下面,foo将在编 译时报错:
#pragma strictfunctionStart (){    var foo =GetComponent(MyScript);    foo.DoSomething();}
(3)缓存组件查找
另一个优化是组件缓存。这种优化需要一些代码并且不是总有必要。但是如果你的代码真的很大,并且你需要尽可能的性能提升,它会是很好的优化。
当你通过GetComponent获取一个组件或一个变量时,Unity必须从游戏物体里找到正确的组件。这时你便能通过一个缓存组件引用到一个私有变量。
将:
functionUpdate () {    transform.Translate(0, 0, 5);}
转换为:
privatevar myTransform : Transform;functionAwake () {    myTransform= transform;}functionUpdate () {    myTransform.Translate(0, 0, 5);}
后面的代码运行较快,因为Unity不用在每一帧寻找变换组件。同样,支持脚本组件。你可以使用GetComponent获取组件或其他快捷属性。
(4)使用内置数组
内置数组是非常快的。ArrayList或Array类很容易使用,你能轻易添加元件。但是他们有完全不同的速度。内置数组有固定长度,并且大多时候你会事先知道最大长度然后填充它。内置数组最好的一点是他们直接嵌入结构数据类型在一个紧密的缓存里,而不需要任何额外 类型信息或其他开销。因此,在缓存中遍历它是非常容易的,因为每个元素都是对齐的。
privatevar positions : Vector3[];functionAwake () {    positions =newVector3[100];    for (var i=0;i<100;i++)    positions = Vector3.zero;}
(5)如果没有必要不要调用函数
最简单,最好的优化是执行最少的工作。如,当一个敌人在远处时,让他处于睡眠状态,大多时候是可行的。直到玩家靠近,可以这样处理:
functionUpdate (){// 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中方法做这个:
1)使用 OnBecameVisibleOnBecameInvisible。这些调用与渲染系统相联系。一旦摄像机看到物体,OnBecameVisible 将被调用,不看他时,OnBecameInvisible被调用。这有时很有用。但是对于AI来讲通常是没有用的,因为你背转敌人,敌人就变成不可用了。
functionOnBecameVisible () {    enabled =true;}functionOnBecameInvisible (){    enabled = false;}

2)使用触发器。一个简单的球形触发器能引发惊人效果。你可以调用OnTriggerEnter/Exit,当进入你想要的作用范围。
functionOnTriggerEnter (c : Collider){    if(c.CompareTag("Player"))    enabled = true;}functionOnTriggerExit(c : Collider){    if (c.CompareTag("Player"))   enabled = false;}

使用协同程序。Update的问题是他在每帧都发生。很可能只需要5秒钟检查一次玩家的距离。这可以节约大量的处理周期。

An increasing number of peopleare beginning to realize that education is not complete with graduation.

 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值