推广

Unity3D 项目优化-CPU方面

iseeyu2年前 (2024-02-22)推广137

image.png

  • Dynamic Batching 动态批处理
    首先要明确一点,Unity 3D的Draw Call动态批处理机制是引擎自动进行的,无须像静态批处理那样手动设置Static。举一个动态实例化Prefab的例子,如果动态物体共享相同的材质,则引擎会自动对Draw Call优化,也就是使用批处理。
    总结一下动态批处理的约束,也许能从中找到为什么动态批处理在自己的项目中不起作用的原因。
    (1)批处理动态物体需要在每个顶点上进行一定的开销,所以动态批处理仅支持小于900顶点的网格物体。
    (2)如果着色器使用顶点位置、法线和UV值3种属性,那么只能批处理300顶点以下的物体;如果着色器需要使用顶点位置、法线、UV0、UV1和切向量,那只能批处理180顶点以下的物体。
    (3)不要使用缩放。分别拥有缩放大小(1,1,1)和(2,2,2)的两个物体将不会进行批处理。
    (4)统一缩放的物体不会与非统一缩放的物体进行批处理。
    (5)使用缩放尺度(1,1,1)和(1,2,1)的两个物体将不会进行批处理,但是使用缩放尺度(1,2,1)和(1,3,1)的两个物体将可以进行批处理。
    (6)使用不同材质的实例化物体(instance)将会导致批处理失败。
    (7)拥有lightmap的物体含有额外(隐藏)的材质属性,例如lightmap的偏移和缩放系数等。所以,拥有lightmap的物体将不会进行批处理(除非它们指向lightmap的同一部分)。
    (8)多通道的shader会妨碍批处理操作。比如几乎Unity 3D中所有的着色器在前向渲染中都支持多个光源,并为它们有效地开辟多个通道。
    (9)预设体的实例会自动地使用相同的网格模型和材质。
    所以这里建议各位开发者尽量使用静态的批处理。

  • 对物理组件的优化
    第一点是设置一个合适的Fixed Timestep
    第二点是尽量不要使用网格碰撞器(mesh collider)。
    不选择mesh collider是因为什么原因呢?这是由于mesh collider实在是太过于复杂了。mesh collider利用一个网格资源并在其上构建碰撞器。对于复杂网状模型上的碰撞检测,它要比应用原型碰撞器精确得多。标记为凸起的(Convex)的网格碰撞器才能够和其他网格碰撞器发生碰撞。手机游戏自然无须这种性价比不高的东西。

  • 处理内存,却让CPU受伤的GC
    虽然GC是用来处理内存的,但的确增加的是CPU的开销。因此它的确能达到释放内存的效果,但代价更加沉重,会加重CPU的负担,因此对于GC的优化目标就是尽量少的触发GC。
    首先要明确所谓的GC是Mono运行时的机制,而非Unity 3D游戏引擎的机制,所以GC也主要是针对Mono的对象来说的,而它管理的也是Mono的托管堆。清楚这一点,也就明白了GC不是用来处理引擎的assets(纹理、音效等)的内存释放的,因为Unity 3D引擎也有自己的内存堆,而不是和Mono一起使用所谓的托管堆。
    其次要清楚什么东西会被分配到托管堆上,那就是引用类型。比如类的实例、字符串、数组等。而作为int类型、float类型,包括结构体struct其实都是值类型,它们会被分配在堆栈上而非堆上。

  • GC在以下两种情况下会触发。
    (1)堆的内存不足时,会自动调用GC。
    (2)作为编程人员,自己也可以手动调用GC。
    GC的优化说白了也就是代码的优化。
    需要注意以下5点:
    (1)字符串连接的处理。因为将两个字符串连接的过程,其实是生成一个新的字符串的过程。而之前旧字符串自然而然就成为了垃圾。而作为引用类型的字符串,其空间是在堆上分配的,被弃置的旧字符串的空间会被GC当作垃圾回收。
    (2)尽量不要使用foreach语句,而是使用for语句。foreach语句其实会涉及到迭代器的使用,而据说每一次循环所产生的迭代器会带来24Bytes的垃圾。那么循环10次就是240Bytes。
    (3)不要直接访gameobject的tag属性。比如“if (go.tag == “human”)”最好换成“if (go.CompareTag (“human”))”。因为访问物体的tag属性会在堆上额外的分配空间。如果在循环中这么处理,留下的垃圾就可想而知了。
    (4)使用“池”,以实现空间的重复利用。
    (5)最好不用LINQ的命令,因为它们会分配临时的空间,同样也是GC收集的目标。而且笔者不用LINQ的一点原因就是它有可能在某些情况下无法很好地进行AOT编译。比如“OrderBy”会生成内部的泛型类“OrderedEnumerable”。这在AOT编译时是无法进行的,因为它只是在OrderBy的方法中才使用。所以如果你使用了OrderBy,那么在iOS平台上也许会报错。

  • 对代码质量的优化
    5个方面需要注意:
    (1)以物体的Transform组件为例,我们应该只访问一次,之后就将它的引用保留,而非每次使用都去访问。有人做过一个小实验,就是对比通过方法GetComponent<Transform>()获取Transform组件, 通过MonoBehavor的transform属性去获取,以及保留引用之后再去访问所需要的时间。
    1)GetComponent=619ms。
    2)Monobehaviour=60ms。
    3)CachedMB=8ms。
    4)Manual Cache=3ms。
    (2)最好不要频繁使用GetComponent,尤其是在循环中。
    (3)善于使用OnBecameVisible()和OnBecameVisible()来控制物体的update()函数的执行以减少开销。
    (4)使用内建的数组,比如用Vector3.zero而不是new Vector(0, 0, 0)。
    (5)对于方法的参数的优化,善于使用ref关键字。值类型的参数是通过将实参的值复制到形参,来实现按值传递到方法,也就是通常说的按值传递。“复制”总会让人感觉很笨重。比如“Matrix4x4”这样比较复杂的值类型,如果直接复制一份新的,反而不如将值类型的引用传递给方法作为参数。

  • 扫描二维码推送至手机访问。

    版权声明:本文由西安泽虎代运营发布,如需转载请注明出处。

    转载请注明出处https://www.0291.com.cn/post/55949.html

    相关文章

    百科营销怎么做?百度百科是如何进行企业或个人的营销,几点 ...

    说到搜索引擎优化,很多人都会想到利用论坛、贴吧、博客、问答、友情链接等方式来自己的网站。确实,推广网站的方式有很多种,这些都是众所周知且常用的方法,但是百科词条这种推广方式很容易让人忽略,原因是百科词条的审核力大,非常严格,带上网站链接的词条通过率普遍都很小。因而,站长们在...

    知客CRM:将销售人员效率提高三分之一的实用策略

    知客CRM:将销售人员效率提高三分之一的实用策略

    30 多年来,我一直直接参与销售、管理和领导销售人员,并为销售组织提供咨询服务。有两种趋势一直存在:对销售技术和销售队伍自动化的重视和投资的增加、销售人员效率持续下降,或者销售人员实际花在销售上的时间减少。The Aberdeen Group 和 Docurated最近的研...

    媒体对网站营销推广所起的作用。

    媒体对网站营销推广所起的作用。

    不管是纸媒还是电视台,在媒体这个行业呆过一段时间的老手,相信他们都了解一个事实。简单的广告只是媒体宣传的初级阶段,造势与合作才是关键。 一、与媒体合作各位请记住一点,不管任何合作,最重要的就是要掌握对方的意图,力争达到双赢,这是合作的前提和基础,很多朋友都认为媒体一向都是强势群体,一个小网站推广能...

    网站导航制作需要留意的7大关键点。

    网站导航制作需要留意的7大关键点。

    网站导航制作直接影响着整个网站的表现,好的网站导航制作可以让用户快速找到他们所需求的信息。否则,用户根本就不会去访问网站内页,掉头走人,如同自己“赶走”用户。中联科技认为,如果想把网站导航制作好就需要留意7大关键点。 1、主导航夺目明晰 主导航通常表现为一级目录,经过它们用户和蜘蛛程序都可以层层...

    网站的常见结构有哪几种

    网站的常见结构有哪几种

    网站的常见结构有哪几种?网站结构是指网站中页面之间的层次关系 对搜索引擎优化而言,优秀的网站结构优化应该包括网站物理结构优化和逻辑结构优化两个方面,一种是网站的物理结构,一种是网站的逻辑结构。下面我们来分析一下这两种结构。 网站的物理结构: 网站物理结构是指网站目录及所包含文件所存储的...

    小编教你网站推广优化一般流程有哪些。

    小编教你网站推广优化一般流程有哪些。

    理论上针对不同类型的网站,SEO策略是不完全相对,但基于搜索引擎网站排名的原理,对于任何一个网站的优化,都具有一定相似的流程。那么,如何优化网站,优化一般流程有哪些? 1、网站架构设计 在做网站信息架构的时候,我们并不单纯的只是简单的罗列网站的栏目结构,同时我们还需要考量: ① 网站...

    现在,非常期待与您的又一次邂逅

    我们努力让每一部企业宣传片和抖音短视频成为商业大片