技术分享连载(七)

技术分享连载(七)

本期话题:WaitingForJob函数导致的卡顿是否由于渲染压力过大、Shader代码里报错的原因、Profiler中没有引用的资源是否还在内存中、如何降低ParticleSystem.Geometryjob的CPU消耗...

PS:近期不少开发朋友们反映侑虎君被“模仿”了,小编赶紧过来打个假。请开发者们认准我们官方网址www.uwa4d.com,不要被忽悠!


运行性能

Q1:如下图,我们发现WaitingForJob这个函数消耗过高导致了卡顿,请问该卡顿是否由于渲染压力过大导致?

UWA Tech Doc

UWA Tech Doc

从图中看,该线程最后是在等待 Canvas.sortjob,而这是 UI 排序造成的开销(自Unity5.2版本开始,UGUI的部分计算已经移出了主线程)。
详情参考:http://blogs.unity3d.com/2015/09/07/making-the-ui-backend-faster/
因此理论上,这是 UI 的 canvas.sortjob 在指定的时间上没有完成,从而使得渲染线程等待,且最终导致主线程进行等待而造成的开销。


物理

Q2:UWA的报告中指出我们所使用的刚体超出了限制,我们经过测试发现只要使用CharacterController就会产生一个隐藏的刚体。而我们的角色移动是会使用CharacterController的。 为了避免这种情况,我们使用了CapsuleCollider来替代CharacterController接受点击,同时使用设置位置的方法来替代CharacterController的move。

1. 请问这样做是否有风险,并且是否可以降低我们在刚体和物理系统方面的开销呢?

2. 同期我们观测到了一个以前没有关注过的警告。其内容为:
Static Collider.Move (Expensive Delayed cost),请问该报错是否与我们的调整相关?能够导致该警告的原因可能会有哪些呢?

  1. 多数情况下,RigidBody + CapsuleCollider 与 CharacterController 相比会高效一些,因为 move 函数本身会进行较复杂的模拟运算;
  2. Static Collider.Move (Expensive Delayed cost) 意味着场景中有静态碰撞体(不带有RigidBody的Collider)发生了移动,而该操作在Unity 4.x版本的PhysX 中会在后续的模拟中产生较高的开销,但在 5.x 中理论上开销并不明显。如果要消除该问题,只需定位到发生位移的Collider并挂上RigidBody 组件,打开其is kinematic 选项即可。

图形渲染

Q3:我在shader里这么写的代码

o.texcoord1 = vec2(mod(v.texcoord.x,1.0),mod(v.texcoord.y,1.0));  

但是报错 undeclared identifier 'mod' at line 106 (on d3d11),请问是什么原因导致的呢?

报错表明mod在d3d11的Shader中是未定义的,如果开发团队无需在d3d11的平台上使用该 Shader,则可以添加以下预编译指令:

#pragma exclude_renderers d3d11

如果Shader依旧无法正常显示,那可能是因为在Editor中使用的是 DX11(可以从标题栏中看出)。 可以尝试修改DX9的参数 :Build Settings -> 点击 PC, Mac ... -> Player Settings(不需要点击 Switch Platform) -> 去掉 Auto Graphics API for Windows 的勾选,只保留 Direct3D9。同时,开发团队也可以直接使用 fmod 替换 mod,理论上 fmod 在各个平台都是支持的。


运行性能

Q4:我们在查看《六龙争霸测评精讲》时,看到下图中的GC的调用,请问该数值的是取决于明式调用System.GC.Collect()这个方法吗,还是指系统自动GC的频率?

UWA Tech Doc

手动触发System.GC.Collect和系统触发GC都属于GC的调用。除iOS平台外,Unity项目的GC调用是由Mono来控制的。其主要有两种方式,一种是系统每隔一段时间调用一次,一种则是当堆内存分配过大过快时被触发。
每次GC调用均会造成一定程度上的卡顿,从而降低项目运行的流畅度。因此UWA测评中专设了GC调用详细检测,欢迎开发者上传项目测试!

UWA Tech Doc

UWA Tech Doc


内存管理

Q5:我们的游戏玩了20分钟后,Texture2D的内存涨到了60MB多,并且重复的资源很多,是否由于没有卸载完全?还是打包AssetBundle依赖性的问题?用的是UGUI。

UWA Tech Doc

UWA Tech Doc

存在如下两个原因:
1、AB依赖关系打包存在问题,即atlas没有被依赖打包;
2、加载卸载的管理问题,可能是加载了一次后被一个Container索引了,这时又加载了一次同样的AssetBundle又被索引。如果这些一直没有释放,也会出现这种情况。


资源加载

Q6:如下图,我们在Unity 5.3.0中使用粒子系统时会触发一个ParticleSystem.Geometryjob的操作,并且该操作十分消耗CPU,请问怎么解决?

UWA Tech Doc

该问题已经确认是Bug,且已在Unity 5.3.2中修复。
开发者需要关注下自己的开发版本,5.3.2以前类似情况的项目可以参考一下。


资源加载

Q7:如下图:我在Profiler中看到这些没有引用的资源,他们是否还在内存中?

UWA Tech Doc

是的,凡是在Unity Profiler中能看到的资源就会保留在内存中。对于这种资源,在切换场景时调一下UnloadUnusedAssets API就可以释放。


近期活动

如何规避性能项目运行卡顿的问题?内存泄露、资源冗余如何定位?代码质量影响整体性能如何改良? 4月9日上海,我们延续性能优化的主题,搭配国民级手游《六龙争霸》性能数据深度剖析,使大家对游戏/VR应用的运行性能有更为深刻的认知。

活动详情请戳下图↓

UWA Tech Doc


【技术小札】是UWA推出的技术交流栏目,我们会将开发团队中反馈的常见问题加以总结并梳理在此,以供大家参考。同时如果你也是个热爱分享、愿与大家抱团进步的程序员,欢迎加入UWA的QQ群(793972859),与我们奇文分享,疑义相析。