UWA问答 | 博客 | 游戏及VR应用性能优化记录分享 | 侑虎科技 - 资源管理
type: channel
link: https://blog.uwa4d.com/tag/资源管理
items: 如何制作RTS游戏的寻路系统？
items: 技术分享连载（八十五）
items: UWA发布 | 2017 Unity手游体检蓝皮书 — ARPG篇
items: 资源管理也能快如闪电！
items: 给调皮的AssetBundle加上面向对象式加载调试管理
items: 关于Unity加载优化，你可能遇到这些问题
items: 重磅 | UWA性能诊断又添新利器，开启资源优化新篇章 ！

如何制作RTS游戏的寻路系统？
type: item
date: 2018-04-13T04:44:00+03:00
description: 本期聚集话题：RTS游戏的寻路系统、AssetBundle打包后md5不同、UGUI中3D血条优化问题、如何快速改变场景里一部分物件的外观效果... 这是第107篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间15分钟，认真读完必有收获。文末，我们的互动话题是：能耗发热怎么办？期待你的灼见！ UWA 问答社区：answer.uwa4d.com UWA QQ群：793972859（仅限技术交流） 本文封面图来源：RTS手游《战地指挥官》 http://zdzhg.53mayi.com 寻路 Q1：我们在做一个RTS游戏，开始用的是Unity自带的NavMesh的寻路，但发现这个并不适合RTS多人寻路，因为总会出现阻挡和闪跳的问题。看Asset Store上的A* path插件评论说在碰撞上有问题，不知道大家是否能提供比较成熟的解决方案？ 我们上一个项目是RTS项目，刚开始寻路问题解决方案过程中遇到过和你相似的疑惑，修改探索和调教了很长时间，分享几点供题主参考下。 先上结论：我们采用了两层结构 A Start Pathfinding Project Pro + Unity NavMesh。 1）主体寻路方案使用 A Start Pathfinding Project Pro 这个插件中传统的网格形式，并进行了深度修改扩展，主要是满足寻路过程的通路性需要考虑到单位半径大小，这样寻路精度高； 2）使用Unity NavMesh系统作为寻路过程中的碰撞系统，因为你说的很对，这个寻路插件的碰撞有问题，稍后解释。 以上两部分组成“寻路算法+精确碰撞”。接下来说下以上方案的原因和细节。 1、NavMesh寻路速度快但不够精确。RTS还是适合使用传统的四方形NavGrid格子寻路，而且现有的任何寻路算法默认都是不支持考虑寻路单位半径大小对寻路过程的影响，但我们策划绝不允许1米宽的缝隙被一个两米宽的胖子挤过去，如果使用Navmesh并且动态生成阻挡会出现寻路路径是有了，可是由于碰撞问题大的单位会卡在缝隙这里来回“发抖”的情况；这个只能自己动手修改，所以我们买了该插件然后自己从里到外修改，具体修改算法原理和修改后的示意图，你可以参考这里：http://www.cnblogs.com/yaukey/p/rts_unit_traverse_size_based_path_finding.html。 修改完后，每次寻路会将单位的直径大小当做寻路参数之一传入进行寻路。 使用这个插件开启两个线程左右来寻路是我后来调教出的、一个比较理想的结果。然后是地图中各种单位会出生和死亡，当单位站定不动，需要生成阻挡；移动了需要移除阻挡恢复此处的通路性，通过再修改下插件中的DynamicObscule这个组件（原生功能太简单）来实现；我们具体是每个单位都有一个对应的大小的CapsuleCollider空对象挂上这个脚本，单位站定将该物体放置到单位的位置并激活它，单位移动隐藏该空物体即可，这个脚本会引起地图通路性的更新，这个更新是多线程的，这一点是要注意的，通过回调事件来做响应的事情，切记不要在同一帧或者下一帧去做，因为即时性不能保证。这样就能让整个地图一直根据单位来更新通路性。 2、寻路的通路性问题解决了，现在来解决碰撞问题。这个插件自带了碰撞算法，使用的rvo算法，但是据我当初各种调教实验，它的碰撞都达不到我们的要求，单位多了拥挤的时候总是会有些单位站立后变得重叠了，最不能接受的是两个单位完全重叠。在这里我花了相当多的时间都不能修改出的满意的效果。后来想起来recastnavigation作者亲口说过虽然Unity的NavMesh基于此，但是Detour系统经过深度的改写，Detour包含了巡航和碰撞，而实际使用也发现NavMeshAgent之间的碰撞是很精确的，于是我想了个取巧的办法，给地表再铺一层跟AStar插件的寻路面积一样大的NavMesh，但是没有任何的阻挡（理解为一片纯蓝色），同时给寻路单位添加一个NavMeshAgent，然而这个东西只用它的碰撞，而不使用寻路（没有阻挡，任何寻路都是两点直线，可以考虑几乎无开销），这样最后实际的碰撞效果才算达到我们满意的效果。 以上就是我所说的两层含义，我再说下坑和问题。 1）当初开发Unity版本是Unity 5.3.7-5.3.8，插件版本5.x，寻路插件中底层会有Physics.CheckCapsule调用，但是多线程大量调用，会导致底层PhysX物理引擎崩溃，游戏闪退，不必现但是大量的话很容易一下就挂，插件官方论坛也有这个Bug讨论，后来我将此换成了两个 Physics.CheckSphere 调用，目前2017版本没有测试过； 2）我在1中使用的方法，在UWA性能评测中…

技术分享连载（八十五）
type: item
date: 2017-11-07T03:48:00+02:00
description: 本期我们聚集了这些话题：资源管理方式、新版本下UI相机粒子的性能开销、Camera下开启HDR对性能的影响... UWA一下，你就知道~ 我们将从日常技术交流中精选若干个开发相关的问题，建议阅读时间15分钟，认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们，一起探讨。 UWA QQ群：793972859 UWA 问答社区：answer.uwa4d.com 渲染 Q1：我看到很多炫酷的效果都是用Unity的后处理来实现的，要求Camera开启HDR。但是我不知道开了这个选项会不会很耗，在中低端机上能跑起来吗？另外，使用HDR之后，Camera的Rendering Path是不是不能选Forward? 使用HDR可以选Forward，和Rendering Path的选择并不会相互影响。 在手机上单纯开启HDR(fp16)性能的影响并不会很大，各种后处理Pass的开销是要优化的重点。因为一般不会单纯开启HDR而不使用后处理，综合考虑到发热量等因素，不建议低端机器使用HDR和后处理，中高端再开启HDR并配合后处理，并对后处理做基础优化：比如适当降低后处理分辨率，尽量合并多个后处理流程到一个Pass等。 该问题来自UWA问答社区，感谢贺甲提供了回答，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/59f810692f7f63497e0f6baf 渲染 Q2：Unity5.5 运行中，材质球的GI选项在烘焙的时候，代码修改模型Renderer组件所引用的Material属性，SetColor(“_EmissionColor”)，没有实时刷新效果。 代码如下： Renderer[] renderers = (Renderer[])mesh.GetComponentsInChildren<Renderer>(); foreach(Renderer r in renderers) { r.sharedMaterial.SetColor("_EmissionColor", new Vector4(0.5f, 0, 0, 1)); } 测试中发现，必须要Editor中选择这个材质球才能刷新。 经测试发现将材质中的GI设成“Baked“之后，如果_EmissionColor的初始值是0，则Unity会直接关闭Standard Shader的“_EMISSION”Keyword，导致设置_EmissionColor对渲染结果无影响。解决方法是设置同时打开“_EMISSION”Keyword，即加上： r.sharedMaterial.EnableKeyword("_EMISSION"); 该问题来自UWA问答社区，如您对该问题仍有疑问，可以转至社区进行进一步交流。 https://answer.uwa4d.com/question/59f5917ceecc29a735c1321d 渲染 Q3：下面两张图是mate9+OpenGL运行我们项目最高画质时的Proflier截图，Unity 5.6.0p4，可以观察到下图一中第二个Camera.Render出现了一个非常长的等待，这个是我们的UI相机。从图中可以观察到它在等待其他相机完成渲染线程的任务后才开始执行自己的主线程渲染任务。 而下图是关闭了大部分UI，UI相机依然工作，但并没有出现这个异常的等待，我们观察到上图中第二个Camera.Render的首个任务是WaitForJogGroup，并且Job Thread在相同时刻出现了Particle Job，我们怀疑只要这个相机出现了particle system就会出现这种情况，但暂未确定，不知道各位是否有遇到这种情况，以及Unity是不是存在这个问题，如果是5.6的问题，那么后续的版本是否有解决呢？ 这种情况在Unity 5.6版本中经常出现，不管是Unity 5.6.0还是最新的5.6.3，这种情况都是普遍存在的，下图是我们刚刚优化过的一个项目中的Timeline截图（Unity 5.6.3版本），而这种情况在5.6版本之前是很少出现的。 这种问题在我们来看，主要是有两点原因： （1）Unity 5.6版本中将更多的渲染计算从主线程中搬到了渲染子线程中处理，而主线程还需要等待子线程的操作结果才能继续进行，从而造成了问题图二的主线程“等待”现象，即Camera.Render的Self开销； （2）本质原因还是单帧渲染量太大，如题主遇到的UI界面渲染、粒子系统渲染以及蒙皮网格计算等，如果量大都是有可能造成子线程压力过大的，所以虽然很多项目中开启了多线程渲染功能，但还是需要对渲染量时刻保持关注。 目前我们还没有接触过过多的Unity 2017项目，所以目前暂时无法给出统计…

UWA发布 | 2017 Unity手游体检蓝皮书 — ARPG篇
type: item
date: 2017-08-01T04:40:00+03:00
description: 接上期UWA 发布的2017 Unity手游体检蓝皮书MMORPG篇，本期我们将深度剖析ARPG的游戏性能发展情况。此份蓝皮书收集了提交到www.uwa4d.com上的所有项目，我们从总体性能数据、引擎各模块开销、内存占用等方面进行了汇总分析，呈现Unity手游行业现状。 这是侑虎科技第275篇原创文章，欢迎转发分享，未经官方授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们，一起探讨。（QQ群：793972859） 报告目录： 一、ARPG手游总体性能开销分析 二、ARPG手游CPU模块性能开销分析 三、ARPG手游内存模块性能开销分析 四、ARPG手游资源管理分析 五、UWA对于ARPG手游研发团队的建议 一、ARPG手游总体性能开销分析 iOS设备的CPU性能普遍高于Android设备，Android设备的CPU均值主体范围为12.4~66.2 ms，iOS设备的CPU均值主体范围为7.0~57.5 ms。 我们选择了测评次数最多的四款机型来进行统计，这四款机型分别是红米2、红米Note2、华为6Plus和三星S6。 1）大部分ARPG手游在中低端设备的性能开销较高，在Android设备上，CPU耗时集中在17~50ms区间，而在iOS设备上，CPU耗时集中在33ms以内。 2）相较2016年同期，2017 Q2 ARPG手游在低端设备上的CPU开销均值增长5.8 ms。 无论是高、中、低端的Android设备，渲染、UI、加载/代码都是需要研发团队重点关注的，它们的消耗总和占了总开销的80%。 下面我们就来具体分析这些主流模块的开销情况。 二、ARPG手游CPU模块性能开销分析 1、渲染模块 严重程度：地狱 为了能够更好地反映出各个性能参数的整体使用情况，我们统计了每种性能参数的主体使用范围，其范围区间是[5%~95%]，以下数据中P5代表5%，P95代表95%。 在Draw Call使用上，ARPG手游的使用程度略低于MMORPG手游，且对Draw Call的控制同样较高，UWA建议Draw Call占用的P95 < 200，76.3%的项目可以将其控制在这个范围内。 1）ARPG手游的场景渲染三角形面片数量普遍较高。且设备性能越高，数量峰值越高。经过统计，在中低端设备中，46.5%的项目能将渲染三角形面片数控制在100K以下。 2）ARPG游戏的场景复杂程度明显低于MMORPG游戏，渲染面片峰值要比MMORPG手游平均低50K。同时，虽然2016 Q4和2017 Q1渲染面片数量大幅上升，但2017 Q2开始回落趋势较为明显。 Graphics.Bilt操作平均每次调用的CPU耗时主要分布在: 0.1~8.5ms。该项CPU开销在低端设备上的上升趋势较为明显，但在2017 Q1大幅下降。这主要是因为，在2017 Q1后，ARPG项目普遍开启了多线程渲染功能。 2、UI模块 严重程度：地狱 使用NGUI作为UI解决方案的项目占据了较高的比例，但从趋势上来看，UGUI从2016 Q3开始，增速非常明显。通过进一步分析，我们发现近大半年来的新ARPG手游中，使用UGUI的项目显著增加，从而大幅提升了UGUI在ARPG项目中的使用占比。 下面我们将分别说明NGUI和UGUI的CPU耗时和堆内存占用情况。 UI模块的性能开销依然很高，也是我们统计中的第二大性能杀手。在中低端设备上，超过90%的研发项目在UI端都面临较为严重的性能问题，主要体现方面与MMORPG游戏类似，功能界面复杂、同一时刻需要更新的Panel多等。但ARPG的平均耗时要略低于MMORPG，这是因为ARPG主要仍以推图形式为主，其在战斗副本中的玩家是预先固定的，大量玩家同屏打怪的情况很少出现。 经统计，NGUI中堆内存每10000帧分配的主体范围为 6.0~81.7 MB，UGUI中堆内存每10000帧分配的主体范围在12.3 MB以内。从堆内存分配来看，UGUI远低于NGUI。 3、逻辑代码 严重程度：噩梦 1）GC触发频率很高，是造成卡顿的主要原因之一，目前只有12.5%的项目可以将GC的触发频率控制在1000帧/次以上。 2）在2017年GC平均耗时趋势虽有所上升，但相比于2016年已经大幅降低。 1）Instantiate实例化操作平均每次调用的CPU耗时主要分布在: 1.2~43.5 ms，且主要集中在10ms以内。 2）Instantiate实例化耗时在2017 Q2之后大幅下降，这说明越来越多的研发团队开始重视项目运行时的资源管理。 Shader.Parse 操作是比较突出的性能杀手，目前平均每次调用的CPU耗时主要分布在 4.4~145.2ms。但随着越来越多团队了解该项的耗时特性后，该项的CPU耗时呈现出较为明显的下降趋势。 4、动…

资源管理也能快如闪电！
type: item
date: 2017-05-26T05:34:00+03:00
description: 几乎所有的Unity开发者都曾为AssetBundle管理机制填过“坑”。如何巧妙合理地设计AssetBundle的依赖关系来尽可能减小包体的大小？怎样针对不同的资源选择不同的API来提高加载的效率？想必你也肯定有过类似的疑问，今天我们将结合UWA性能检测与分析报告，为大家分享针对资源管理中的优化方式，从而高效地定位资源漏洞并优化解决。 我们将针对资源管理分别介绍优秀级和大师级优化方式。（没错，今天就是为那些将要晋升为CTO的工程师准备的福利！） 一、优秀的优化方式 1. 查看资源加载（卸载） 在UWA性能测评报告的资源管理页面中，研发团队可以方便地查看项目运行时资源的加载情况，如通过Resources.Load/LoadAsync、AssetBundle加载（卸载）的具体资源信息。 我们提供了三种模式供大家自由地查看：查看所有资源、查看指定场景所用资源和查看指定帧所用资源。 通过该界面，研发团队可以明确： （1）项目运行过程中，哪些资源是通过Resources.Load/LoadAsync来加载的； （2）项目运行过程中，哪些资源存在频繁加载的情况； （3）项目运行过程中，资源加载的具体时间点； （4）项目运行过程中，资源加载的具体耗时。 建议大家通过以上四点，来快速定位资源加载存在的问题和漏洞，并及时对加载逻辑代码进行完善。 2.关注AssetBundle文件加载/卸载方式 在UWA性能测评报告中，大家可以直接查看项目运行时AssetBundle文件的加载方式。目前关于Unity AssetBundle的主流加载方式有以下四种：New WWW、WWW.LoadFromCacheOrDownload、AssetBundle.Load/CreateFromFile和AssetBundle.Load/CreateFromMemory。 点击上图中每个Widget，就可以看到该加载方式的具体使用情况。下图为New WWW在游戏运行过程中的整体调用情况； 建议研发团队对LoadFromMemory谨慎使用。由于LoadFromMemory的加载效率相较其他的接口而言，耗时明显增大，因此我们不建议大规模使用。如果希望对AssetBundle文件加密，那么建议仅对重要的配置文件、代码等进行加密，对纹理、网格等资源文件则无需进行加密。因为目前市面上已经存在一些工具可以从更底层的方式来获取和导出渲染相关的资源，如纹理、网格等，因此，对于这部分的资源加密并不是十分的必要性。 3.关注AssetBundle的具体使用情况 在UWA性能测评报告中，研发团队可以从以下几个方面直接查看AssetBundle文件的具体使用情况。 通过该界面，研发团队可以明确： （1） AssetBundle文件在项目运行过程中的具体加载时间点； （2） 具体加载的AssetBundle文件名称； （3） 具体AssetBundle文件的存放位置； （4） 每个AssetBundle文件的加载次数。 注意：UWA建议研发团队时刻关注AssetBundle文件的加载次数，查看是否存在同一AssetBundle被持续加载的情况，如上图中蓝色方框1和2所示。 二、大师级优化方式 除了以上提及的优化方式，下文我们将介绍性能优化中省时高效的黑科技，如何在极短时间内快速定位到问题的瓶颈，节省优化的时间，这些分析利器你千万不可错过！ 1.查泄露、查驻留，一个都不能少 在UWA性能测评报告的资源管理页面中，研发团队可以方便地查看项目运行时AssetBundle在内存中的驻留情况，从而快速看到AssetBundle是否存在泄露的问题。 上图的AssetBundle使用数量在不断上升，很可能存在AssetBundle资源泄露问题。 同时，研发团队也可以查看指定AssetBundle文件在项目运行过程中的的加载和卸载情况。点击上图的某一帧或某一场景，我们就能查看对应的具体AssetBundle信息，包括具体名称、存放的位置、加载方式、内存中的驻留时长和由该AB加载出的资源数量。 除此之外，UWA报告也提供资源内存的泄漏分析，通过资源的“场景比较”如同种类型场景或同一场景进行比较、不同类型场景进行比较等功能，从而更快速地找到存在“泄露”问题的资源。 2.时刻关注GameObject的Instantiate/Destroy情况 在UWA性能测评报告的资源管理页面中，研发团队不仅可以查看到项目运行时GameObject的Instantiate和Destory调用次数，还可以详细查看每次调用时的具体GameObject信息。 建议研发团队对表格中操作次数大于50的GameObject进行详细分析，避免同一GameObject频繁Instantiate和Destory的操作出现。 3.关注GameOb…

给调皮的AssetBundle加上面向对象式加载调试管理
type: item
date: 2017-03-08T08:48:00+02:00
description: 相信每一个使用Unity引擎的老司机都会被它的一个功能所困扰过——AssetBundle。本文从加载、调试、异步、垃圾回收、路由5个方面，介绍了基于面向对象思想设计的用来进行AssetBundle加载的ResourceModule管理器。 一、变味的易用性 Unity是一款主打易用性的游戏引擎。它支持开发者可以低门槛、快速容易地使用Unity开发游戏，所以Unity在最初以类似JavaScript、类似Python的脚本语言作为主要开发语言。目前，Unity几乎已经成为手游开发的首选方案了，其自身的功能和各种围绕它的技术生态日趋完善，C#语言也当仁不让地成为首选开发语言。 但是，她的骨子里依旧还是那个标榜易用性的游戏引擎，由于她“易用”这个特点，开发团队如果在开发之初按照Unity标准的易用方式来制作游戏，到了后期就免不了出现各种各样的坑，需要花费大量的时间去重新重构和代码维护。最典型的情况就是： 一个开头快速功能迭代开发的游戏，直到中后期才萌生热更新的需求，而在Unity里做资源热更（AssetBundle）和代码热更（Lua）是一个不小的工作，需要耗费相当多的精力。 怎么办？加班或延期呗。 回想使用Unity这5年的搬砖经历，Unity里最令我沮丧的功能是它的AssetBundle——不论是打包还是加载，都要花费开发人员大量的时间成本去研究和应用。你以为它可以像Resource.Load那样轻松加载资源？不，它还要手工码代码打包；你以为打包完了就能直接加载调用了？不，它还要在加载时注意处理依赖关系。 二、从Unity的资源方式说起 如前面所说，Unity是一款主打易用性的游戏引擎。它的资源打包方式有两种。 Unity资源方式 一种是使用Resource模式，这种模式更像是端游时代的资源打包方式，把所有的游戏资源打包成一整块文件，然后通过索引文件去记录索引，各个资源文件散落在不同文件里的不同索引位置。比如说，暴雪公司的魔兽世界、魔兽争霸的mpq文件就是这样的一个思路。 这种方式完全体现了Unity的易用性，比如一个图片，不管它是PNG、TGA还是PSD，只要丢到Unity里，都会被统一转化成Unity的Texture格式，简单、傻瓜，非常适合小游戏的开发。但是它也有缺点，就是每一次发布最终编译包的时候，都会重新对资源进行一次打包，速度非常慢，这也反映出它的致命问题: 由于资源全部堆砌在一块了，要替换其中的资源就变得困难——难以进行资源热更新。 另一个种模式，AssetBundle模式。相比较之下，这个模式看上去就像后来迭代版本的时候加出来的一个功能——基于原有Resource模式的不足，提供一个对资源控制更自由的方式。 在Resource模式中，开发者几乎不用操心他们资源管理的技术细节。直接使用编辑器进行资源编辑，用完以后直接打包最终程序就可以了。而Asset Bundle模式则需要自己进行资源的打包加载管理。 Unity AssetBundle打包方式进化 在Unity 5.x之前的版本——3.x和4.x中，AssetBundle是一个非常难用的功能。你不仅要操心资源的管理规范，还要写大量的代码控制它们的打包，更要命的是，除了打包速度慢，还有数之不尽的坑。相信不少开发团队都在AssetBundle上花费过不少精力和时间。 我经历过了4个不同的中大型游戏规模的Asset Bundle打包，躺过其中相当多的坑，逐渐开始掌握它的特征。回头仔细一想，其实很多坑完全是没有必要的，但是前提是在设计之初就给予高度重视，提炼统一的方案，这样才不会导致后期失控的状况。 在Unity 5.x里，官方推出了一个全新的打包方案，对于程序员而言，可以仅用一行代码打包所有的AssetBundle。尽管它里面还是有一些坑，可是却大大减轻了开发团队的工作。打包方式变简单了，大家可以集中精力研究怎么更好地去把这些AssetBundle加载起来了。 三、更好的方式去加载AssetBundle AssetBundle加载资源的API非常简单，核心其实只是两类函数，一类同步，一类异步。 相信每一个游戏开发团队都在官方的这些AssetBundle加载API基础上，封装出自己的加载管理类，这几乎是必须的。封装的方式千奇百怪，怎么样去封装会比较好？ 接下来我所讲述的是一种模仿面向对象的AssetBundle加载管理类封装方式，实现方便加载的同时，又可以更容易地进行实时调试。 这种基于面向对象的方式来设计的AssetBundle加载管理器，我们给他一个名字叫ResourceModule，方便下文讲述。它的主要目的是为了让开发者在方便加载资源的同时，提供方便的实时调试功能，并且你会在这个过程中了解到资源文件的热更新策略。 下面将会分成五个部分来介绍ResourceModu…

关于Unity加载优化，你可能遇到这些问题
type: item
date: 2016-11-08T11:14:00+02:00
description: 关键字 资源加载、卸载 Instantiate 实例化 资源管理方式 一、资源加载 Q1：将Shader独立打包，如果我在启动游戏的时候加载一次，那么之后切换场景是不是就不用每次都加载了？ 确切地说，要达到后续Shader都不出现加载开销，需要满足以下两个条件： （1）包含Shader的AssetBundle文件常驻内存； （2）Shader已经全Load加载好； 只要满足这两个条件，后续加载好的GameObject，但凡依赖于这些Shader的，都会直接拿来进行使用，而不会再有加载和解析开销。 Q2：假设有两个界面Panel A和Panel B，它们均依赖一个共享Atlas C。AssetBundle打包时，如果我们将其分别打包的话，那么在使用时是否不能将AssetBundle C进行卸载？如果在加载Panel A和B之前，将Atlas C加载到内存中，但是将AssetBundle C进行卸载，那么在加载和实例化Panel A和B时，是否会出问题？ 是的，不仅是Panel和Atlas，只要是A或B依赖于C，就必须保证在加载或实例化A或B时，C的AssetBundle一定存在于内存中。如果之前将C对应的AssetBundle进行卸载，则加载或实例化A和B时，引擎将无法自动将C绑定给A和B进行使用。 关于AssetBundle依赖性打包，我们已在之前的分享【揭开AssetBundle庐山真面目】中有所提及。 Q3：请问这个Loading.UpdatePreloading是什么东西，为什么会突然那么高？一般情况下有没有什么优化的办法？ 这是Unity引擎最主要的加载函数。该项一般在切换场景时或主动动态加载资源时较大。 一般来说，加载资源越多、越复杂，则其反映的Loading.UpdatePreloading耗时则越大。 优化之前，必须先定位该函数的CPU占用瓶颈。下图则为我们的案例项目，Loading.UpdatePreloading函数在UWA测评报告中的总体CPU分配情况。通过这个堆栈信息，开发团队就可以对函数的耗时分配一目了然，从而有的放矢地进行优化。 Q4：关于Loading.ReadObject耗费比较高，有什么推荐的方法吗？ Loading.ReadObject是Unity引擎的资源加载函数，一般出现在切换场景和加载API调用时，这其中包括纹理、网格、Material、Shader、AnimationClip等资源。如果你发现该值过高，建议去大力优化加载的相关资源。对于每种资源的加载，我们正在以专题的方式进行总结和分享，建议大家可以先查看以下内容： 加载模块之纹理 加载模块之网格 加载模块之Shader 加载模块之动画片段 Q5：我使用Shader.WarmupAllShaders操作，在后续加载资源还是有CreateGPUProgram出现。(Shader都在一个AssetBundle文件中，都是常驻内存的，不会删掉)是必须使用ShaderVariantCollection来加载Shader吗？ 以上这种问题的较大可能是：Shader被打包到不同AssetBundle中了，WarmupAllShaders仅能对当前内存中的Shader进行warm up。后续如果又有Shader加载进来，则仍然会出现CreateGPUProgram操作。 建议开发团队使用UWA的资源检测工具，检测下AssetBundle中Shader的具体打包情况，查看是否出现了冗余打包的问题。 Q6：我们在UWA上进行了性能测试，发现安卓上同步加载AssetBundle资源会非常耗CPU, 所以近期对资源加载方式做了比较大的调整，绝大部分的资源使用异步加载的形式。 不过这里有个疑问想咨询下: AssetBundle.LoadAsync 和 WWW加载方式都可以用来异步加载AssetBundle, 但是两者API特点也不同, 目前看WWW更耗内存一些, 请问这两种方式更建议使用哪一种 ? AssetBundle.LoadAsync 是在获取了 AssetBundle 对象之后加载其中的资源的；而 WWW 加载是在获取 AssetBundle，两者的作用是不同的。 开发者可能是希望了解异步加载 AssetBundle 的几个 API 之间的区别，相关的接口如下： new WWW WWW.LoadFromCacheOrDownload 这两种方式的具体区别可先参考《你应该知道的AssetBundle管理机制》中的“AssetBundle加载进阶”部分。 二、资源卸载 Q1：切换场景时，卸载上一个场景总感觉耗时，请问大家是否有什么推荐的方案？ 这是Unity在切换场景时调用Resources.UnloadUnusedAssets这个函数造成的，通常情况下其…

重磅 | UWA性能诊断又添新利器，开启资源优化新篇章 ！
type: item
date: 2016-10-11T12:56:00+03:00
description: 小编今天又要安利一个性能诊断的新利器啦—资源管理 强力来袭！ 通过该模块，大家可以对AssetBundle、Asset和GameObject的具体操作情况，以及加载、卸载、Instantiate和Active/Deactive等信息一览无遗，详细直观地查看并分析项目中资源的管理情况，从而高效地定位资源漏洞并优化解决。 目前，该新模块的主要功能如下： AssetBundle加载方式 通过该界面，用户可以快速地了解该项目在测试中其AssetBundle的加载方式、每种加载方式中的总体加载次数和具体AssetBundle加载等情况。 如上图我们可以了解CreateFromFile这个API在测试过程中被调用了729次，并且在下图中定位到该API调用了哪些资源、这些资源的文件位置以及加载次数。 同时，用户还可以通过上图右上角“查看所有资源”、“查看指定场景”和“查看指定帧”来进行详细查看，既能宏观把握AssetBundle使用情况，又可以细致掌控每一帧的AssetBundle加载内容。 此外，用户还可以选择每一个AssetBundle来查看它在项目检测时的具体加载点。 资源加载 资源加载主要提供用户查看项目中资源/AssetBundle文件同步/异步加载的具体使用情况，并通过统计数据来判定资源的加载频率和加载是否正确。 特别地，在报告结果中，我们也就对一些平日开发中忽视的细节进行了友情提示。如上图中的不存在，即表示开发团队希望加载的某资源在指定路径下并不存在，需要引起注意。 资源卸载 该页面提供AssetBundle.Unload和Resouces.UnloadAsset的具体使用情况。与资源加载页面一样，用户能迅速查看其资源和AssetBundle通过何种方式卸载以及其卸载频率。 Instantiate和Active（专业会员权限） 该选项显示GameObject在游戏运行时的Instantiate/Destroy和Active/Deactive的使用情况，重点查看其使用频率，从而帮助研发团队检验缓冲池的使用漏洞。 当然，我们也可以查看每个GameObject的具体使用情况。 以上报告数据来自Heroes of Skyrealm，一款拥有顶级颜值的次时代多人ARPG手游，其海外版已经上线，欢迎关注：http://heroesofskyrealm.com/ 。在此也特别感谢开发商厦门梦加的支持。 PS：一不小心又为大家安利了一款好手游，小编感觉萌萌哒~ 点击此处，抢先来一发UWA性能检测，从此开启资源管理新篇章!