资源审计

原文链接:https://docs.unity3d.com/Manual/BestPracticeUnderstandingPerformanceInUnity4.html

        我们发现在实际项目中发生的许多问题都是由于开发者的“无心之过”——一个疲劳的开发者的临时“测试”更改或是错误的点击会添加低性能的资产,或是改变已经存在的资产的设置。

        对于任何大规模的项目来说,最好有第一道防线来应对人为的错误。相对简单的方法是,编写一小段代码来确定没有人可以添加一张4K未压缩的纹理到项目中。

        然而,这是一个令人惊讶的常见问题。一张4K未压缩纹理占用60MB内存。在低端移动设备,比如iPhone4S,消耗超过180-200MB内存是非常危险的。如果这张纹理被错误的添加,那么这张纹理将会占用到这个应用程序内存预算的三分之一到四分之一,并且导致难以诊断的内存不足的问题。

        虽然现在可以通过5.3内存分析器排查出这些问题,但是我们认为最好是应该确保这些问题一开始就不可能发生。


使用AssetPostprocessor

        Unity编辑器中的AssetPostprocessor类可以用于在一个Unity项目中执行某些最低标准。这个类在资源被导入时收到回调函数。要使用它,就继承AssetPostprocessor并且实现并且实现一个或更多个OnPreprocess方法。重要的一些有:

        ·OnPreprocessTexture

        ·OnPreprocessModel

        ·OnPreprocessAnimation

        ·OnPreprocessAudio

        要获取更多关于OnPreprocess函数的信息,请查看AssetPostprocessor的脚本参考(链接见原网页)。

public class ReadOnlyModelPostprocessor : AssetPostprocessor {

  public void OnPreprocessModel() {

        ModelImporter modelImporter =

(ModelImporter)assetImporter;

        if(modelImporter.isReadable) {

            modelImporter.isReadable = false;

            modelImporter.SaveAndReimport();

        }

    }

}

        这是一个使用AssetPostprocessor对一个项目进行规范的例子。

        这个类会在模型被导入项目时或是模型的导入设置被更改时被马上调用。这段代码仅仅检查看一下是否Read/Write enabled标志位被设置为true(通过isReadable属性表示)。如果是true,那么会使这个标志位强制变为false,然后保存后重新导入该资源,

        请注意,调用SaveAndReimport会导致这段代码被再次调用。然而,由于我们现在可以保证isReadable是false,这段代码不会造成一个无限重新导入的循环。

        在下文的“模型”部分中,会讨论要进行这种改变的原因。


通用资源规则

纹理

禁用read/write enabled标志位

        Read/Write enabled标志位会导致一张纹理在内存中持有两份, 一个在GPU,另外一个在可寻址的CPU内存中(请注意:这是由于在大多数平台上,从GPU内存中回读是非常慢的。从GPU内存中读取一张纹理到一个临时缓冲区用于CPU代码(比如Texture.GetPixel)是性能非常差的。)在Unity中,默认是禁用的,但是它可能会被意外打开。

        Read/Write Enabled只在shader外对纹理数据进行操作时才是必要的(比如使用Texture.GetPixel和Texture.SetPixel这种API),并且应该避免这种情况的发生。


如果可能禁用Mipmaps

        对于相对于摄像机有相对不变的Z轴深度的对象,可以禁用Mipmaps来节省加载纹理时所需的三分之一的内存。如果对象会改变Z轴深度,禁用Mipmaps会导致GPU纹理采样的性能更差。

        总体来说,这对于UI纹理和在屏幕上有恒定尺寸显示的纹理非常有用。


压缩所有纹理

        使用一种对于项目目标平台合适的纹理压缩格式是对节省内存至关重要的。

        如果选中的纹理压缩格式不适用于目标平台,Unity会在加载完纹理后解压纹理,消耗CPU时间和大量的内存。这通常是安卓设备的一个问题,由于其通常因为芯片组的不同而支持非常不同的纹理压缩格式。(详情参阅:https://docs.unity3d.com/Manual/class-TextureImporterOverride.html)


执行合理的纹理大小限制

        虽然这很简单,但是也很容易忘记重新设置纹理的大小或是无意中改变纹理大小的导入设置。对于不同类型的纹理确定一个合理的最大尺寸,并且将其通过代码来执行。

        对于大多数应用程序来说,2048x2048或是1024x1024足以用于纹理图集,512x512足以用于3D模型的纹理贴图。


模型

禁用Read/Write enabled标志位

        Read/Write enabled标志位对模型的作用与上文中其对纹理的作用描述相同。然而对于模型来说它是默认打开的。

        当一个项目会通过脚本在运行时动态修改网格或是要使用网格作为MeshCollider组件的基础,Unity会需要这个标志位启用。如果这个模型不用网格碰撞体并且不会通过脚本修改,那么禁用这个标志位来节省一半的模型内存。


在非角色模型上禁用rig

        默认情况下,Unity对非角色动画会导入一个通用的rig。这就会造成当运行时生成模型时会给其添加一个Animator组件。如果这个模型不是通过动画系统进行运动,那么这个添加操作会给动画系统添加无必要的消耗,因为所有激活的Animator一定会每帧被记录。

        通过禁用不会动画的模型来避免自动添加Animator组件并且可以避免无意的在一个场景中添加不需要的Animator。


对于要进行动画的模型启用Optimize Game Objects选项

        Optimize Game Objects选项(在Rig选项卡中)对于要进行动画的模型来说有显著的性能影响。在这个选项被禁用时,当模型被生成的时候Unity会创造大量的transform层级来对应模型的骨骼构造。transform层级的update是非常昂贵的,尤其是还有其他组件(比如说粒子系统或者碰撞体)关联到其上。它还会限制Unity对多线程网格蒙皮和骨骼动画的计算能力。

        如果模型骨骼构造的特定位置需要被暴露(比如说要暴露一个模型的手以便动态的与武器模型相关联),那么这些位置可以在Extra Transforms列表中被指定的列入白名单。

        一些额外的细节可以在Unity手册的模型导入(https://docs.unity3d.com/Manual/FBXImporter-Rig.html?_ga=2.160227261.1276288412.1550042523-677452303.1550042523)一文中找到。


如果可能使用网格压缩

        启用网格压缩可以减少模型数据所表现的不同通道的浮点数字的位数。这可能会导致较小的精度损失,并且在最终应用于项目之前,美术人员应该检查这种不精确带来的影响。

        指定压缩等级的特定位数使用在ModelImporterMeshCompression脚本参考(https://docs.unity3d.com/ScriptReference/ModelImporterMeshCompression.html)中有详细说明。

        请注意如果可能的话对不同的通道使用不同的压缩等级,所以一个项目可以选择只压缩切线和法线而保留UV和顶点位置不压缩。


请注意:网格渲染器设置

        当添加网格渲染器到预制体或者游戏物体上时,请注意其组件设置。Unity默认开启阴影投射和接收,光照探针采样,反射探针采样,以及移动矢量计算。

        如果一个项目不需要这些功能,可以通过一个自动脚本来确认它们被关闭。任何运行时添加网格渲染器的代码也需要开关这些设置。

        对于2D游戏来说,无意中添加一个阴影选项开启的网格渲染器到场景中会添加一整个阴影pass到渲染循环中,这通常是一个性能的浪费。


音频

适应平台的压缩设置

        使用一个匹配可用硬件的压缩格式。所有的iOS设备都包含一个MP3解压缩器,很多安卓设备都原生的支持Vorbis。

        更进一步讲,导入不压缩的音频文件到Unity中,Unity总是会在构建一个项目时重新压缩音频。无需导入一个压缩的音频然后再次压缩它,这只会造成降低最终音频的片段的质量。


强制音频片段为单声道

        很少有移动设备真的有立体声扬声器。在移动平台上,使导入的音频片段强制变为单声道可以减少其内存消耗的一半。这个设置也适用于所有没有立体声效果的音频,比如说大多数UI声音效果。


减少音频比特率

        这个需要咨询音频设计师,尝试最小化音频文件的比特率来进一步节省内存消耗和减小项目大小。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容

  • 这是摘自Unity官方文档有关优化的部分,原文链接:https://docs.unity3d.com/Manual...
    Wenchao阅读 1,117评论 0 3
  • 我是来自北方的过客 行走在南方的 春风与秋色 我爱北方的寒冷与萧瑟 正如爱南方的孤独和炎热 我是来自北方的路人 行...
    诗客酒魂阅读 215评论 1 2
  • 清晨,我们出发。“妈妈,我最喜欢户外了,待在家里没意思。”我使劲点点头,非常赞许地表示同意。 我们带上画笔、小凳子...
    Hellen66阅读 333评论 0 3