资源管理
Q1:如下图,在UWA性能报告中,我们发现Camera.Render下CreateVBO的开销较高,请问这个是如何引起的?

从图中可以看出,Mesh.CreateVBO是在半透明渲染的开销之下,说明这是半透明物体的渲染引起的。在我们目前测评过的项目中,仅使用NGUI的项目会在此处出现不同程度的CreateVBO的CPU开销。对此,建议研发团队首先确认其UI系统是否使用的是NGUI插件,如果是,则当前NGUI的CPU占用很可能较高,特别是UIPanel.LateUpdate的CPU占用较高。研发团队可在UWA性能测评报告中的UI模块性能页面看到。究其原因,是由于UI Mesh在频繁的重建,对于重建的Mesh,Unity引擎会将其重新传入GPU端进行渲染,这部分开销主要体现在Mesh.CreateVBO和Mesh.DrawVBO中。因此,如果你的项目中使用NGUI插件,并且半透明渲染下Mesh.CreateVBO的开销较高,那么需要研发团队对UI模块进行大力优化了。
资源管理
Q2:FK & Statemachine 状态机占用时间比较高,是否有优化的方法呢?
影响该项的因素较多,一般为:
- 是否开启Optimize GameObjects选项,如果没有,建议开启;
- 场景中Active的GameObject(使用并开启了Animator组件的)是否较多,数量越多,则该项目开销越高;
- GameObject的骨骼数越多、AnimationClip的采样次数越多,则该项开销也越高。
因此,建议研发团队可从以上三种情况入手来优化FK & Statemachine的开销。
资源管理
Q3:伤害检测、还有靠近采集物品时触发可以采集的提示箭头等,我们都使用了碰撞,请问如果不使用碰撞,可以用什么方法代替呢?
使用Trigger也是较为合理的做法,如果想替代,可尝试根据距离、动画运行的时间点来进行判断。
资源管理
Q4:Fixed Timestamp的大小设置多少合理,对物理的开销影响大么?
默认情况下为0.02s,即每20ms会更新一下物理系统和FixedUpdate函数,因此它对物理的开销影响很大。具体设置没有统一的方案,需要根据自身游戏类型和物理系统的使用情况而定。如果项目中对物理系统的使用较小,那么可尝试将该项设置为0.033s,甚至为0.05s,然后在真机上查看这样物理模拟效果是否可以接受。
资源管理
Q5:对Prefab资源的卸载、预览英雄模块、需要卸载英雄角色的资源、动画和材质都可以通过Resources.UnloadAsset(xxx)来顶点清除,而Prefab不行,Prefab 只能用 Destroy + Resouces.UnloadUnused()卸载吗?
Prefab如果想要单独卸载,只能使用DestroyImmediate来实现。同时,考虑到Prefab本身已经是很小的一个壳了,对内存的影响非常小,一般情况下是在切换场景的时候一起释放的。
资源管理
Q6:如果我用WWW加载了一个AssetBundle,创建了一块WebStream内存。这时候我用另一个东西保存这个AssetBundle的引用,然后用WWW给Dispose了,那么这块WebStream内存会释放掉么?
如果仅是www.dispose,但是AssetBundle引用依然保留的话,那么WebStream是不会释放的。WebStream存在两个引用,一个是www对象,一个是加载出来的AssetBundle。仅这两个引用全部消除时,WebStream才会被Unity引擎回收,具体说明可见之前的技术文章:Unity AssetBundle内存管理机制详解。
资源管理
Q7:NGUI的UIEventListener中的OnPress与UIButton的Press状态不能对应上。具体情况是我点击某个按钮并且按住不放,UIButton处于Press状态,然后移出了Button的范围,UIButton的状态变回了Normal,而UIEventListener中的OnPress并没有监听到,必须松开点击才能监听到。它们的Press状态切换有什么不一样呢?
理论上UIButton的OnPress和UIEventListener的OnPress是在相同时间点触发的,即手指按下和手指抬起这两个时间点上。而手指在按住状态下移开按钮时, UIButton的状态会变为Normal,这是因为其响应了OnHover的消息。因此如果要模拟UIButton的行为,至少要配合使用OnPress和OnHover两个消息。
资源管理
Q8:关于UI的Image组件的Sprite剪裁显示问题。因为Image组件上面有ImageType为Filled的选项,通过这个东西可以实现对UI的各种奇妙的显示。因为Mask组件会造成大量的Batches,单独做图会造成算是冗余内存和包体开销,那写个自定义继承Image的组件把这个效果给实现了,按道理是没有问题的,而且在翻看UGUI源代码的时候,也找到了相关片段:


目前对我来说有两个疑问:
1. 假如,我只是单单的想把方形的内容显示成圆形的内容,光靠目前的属性、参数等,能否用一套算法把它算成圆形的呢?
2. 假如说上面的第一个假设是OK的,也假设剪裁成圆形的算法效率也是还行的,那么最终的性能开销是否值得?
对于提问中所提的需求而言,这是一种有意义的做法。即,通过多边形拼成特定形状来避免Mask组件的使用和UI资源的冗余。而对于圆形,由于需要通过多边形来近似地拼出,通常就需要生成较多的顶点数。因此特别需要注意的是:尽可能确保该UI元素是处于“静态”(不会频繁地出现变化的UI元素)的UIPanel中,因为顶点数较多的UI元素会对UIPanel的网格更新带来明显的开销(比如文字的outline效果)。
资源管理
Q9:我发现如果不调用UnloadUnUsedAssets这个函数,则无法销毁通过Instantiate实例化出来的材质(包括纹理)。如果我尝试用Resouces.UnloadAsset来卸载挂在GameObject上的实例化材质, 则会闪退,请问这种情况该如何解决呢?
如果想要直接销毁通过Instantiate实例化出来的材质、纹理等资源,则只能使用DestroyImmediate来进行销毁。研发团队可以参考NGUI中UI Draw Call组件里对动态材质的处理,来加深对动态创建以及销毁的理解。
资源管理
Q10:常用资源类型网格、材质、贴图、动画都是引用或复制+引用的方式被使用,对于那些被引用的资源,需要等引用者不再引用了才能使用Resources.UnloadAsset吗?常用的资源几乎都是引用或引用+复制的关系,所以我对这个接口的理解是用处不大,请问大家是如何使用Resources.UnloadAsset这个接口呢?

是的,一般来说,Resources.UnloadAsset比较适合于在场景中动态释放一些不常使用的资源(比如特殊剧情的资源、音频等等),而对于频繁使用或者需要常驻内存的资源则不适用。使用Resources.UnloadAsset的好处是降低场景切换时的Resources.UnloadUnusedAssets的计算压力,减少不必要的UnusedAssets的查找和检测耗时。
364



被折叠的 条评论
为什么被折叠?



