拖公司的福,有幸去了一趟北京参加了一场Unity3D的交流盛宴,在为期两天的时间内,不只有着技术上收获,也有心灵上的震撼。如今先来讲说技术方面的一些比较重要的知识,可是会跳过Unity3D后续版本的一些新功能介绍,好比新的GUI、动画系统的增强、以及新的AssetBundle打包工具。由于等以后版本出来后,天然会有更加详细的文档以及说明出来。程序员
项目开发、管理和发布策略
四大准则
- 准则一:美术资源量对于程序发布包大小、性能优化、内存占用量的影响,每每超过其余各类因素
- 技术美术和关卡设计师对于游戏性能承担着很是重要的责任
- 程序员每每没法补救因为滥用美术资源而形成的性能问题
- 准则二:项目团队应该经过编写工具来保证美术资源的合法性
- 美术规范文档没法在实际上保证美术资源的合法性
- 程序员应该经过Unity编辑器扩展技术,为美术师实现完整的美术资源合法性检查工具
- 准则三:对渲染效率和内存占用的优化应该在项目实施过程当中反复进行
- 针对CPU端/游戏逻辑的优化每每可以比针过GPU端/Shader的优化取得更大的做用
- GPU/Shader的性能优化应该放在最后进行
- 善用Unity Profilers (这点很是重要,后面会有对这个功能的详细讲解)
- 准则四:从反向工程的角度理解项目开发,以最终须要达到的目的来决定程序的架构设计以及关键技术的方案选择
- 是否须要进行代码的增量更新
- 是否须要严格控制程序发布包的大小
- 是否须要支持低端移动设备等等
Mipmaps
-
凡是3D场景,都应该尽量启用MipMaps缓存
耗费内存,提高CPU性能优化
硬件分级策略
- 为何进行分级
- 移动GPU之间的性能差距可能高达10倍以上
- 效率和效果之间永远存在着矛盾
- 怎么分级
- Resolution分辨率
- Post-processing 后期特效
- MSAA 反锯齿
- Anisotropy 异向纹理
- Shaders
- Fx/particles density, on/off 粒子发射器的数量、密度。单人和多人的不一样处理
初级内存管理策略
一个游戏可使用的内存容量简单的能够理解为:可用内存为整个内存的%50。好比512M的内在可使用256M。多线程
- 控制贴图大小
- 选择合适的压缩格式
- PVRTC,DXT,ATC,ETC
- 使用Prefabs
- 用好AssetBundles
- 编写本身的ObjectPool和LoadManager
- 经过对象池来避免内存的频繁操做,从而避免内存碎片影响到大内存块的申请;切换场景时不释放公共的UI资源
- 经过LoadManager,保证在同一时间段内公载入一个www对象,实现顺序加载
AssetBundle
老的AssetBundle打包的时候有比较多的弊端,依赖打包的时候很麻烦。一个包改变了,相关联的包都要从新打一次包,这个过程会严重的影响开发效率。这个问题在Unity 5.0会获得解决架构
AssetBundle的效率比Resources效率要低。这是没办法的事编辑器
Profiler 性能分析器
Unity3D提供了一个很是强大、很是易于使用的性能分析器,在日常的使用过程当中或多或少都会碰到一些搞不明白的地方,这一次官方给了一个比较详细的解答。一些简单的功能就不在此介绍了,一看就懂。工具
重要的参数指标:
-
GC Alloc性能
记录了游戏运行时代码产生的堆内存分配,这是一个很是重要的参数,甚至比Time更加剧要。ManagedHeap的增大,会加速GC回收的到过。若是这个参数有一个比较高的值或者出如今每一帧中,那么就要引发重视。如下是一些不太引发注意的地方引发的GC分配:优化
- GameObject.GetComponet()会引发GC的分配
- 尽可能缓存组件
- Object.get_name()
- 若是每一帧都须要比较,能够缓存名字
- foreach循环
- 每次foreach会产生一个enumerator
- 尽量避免使用LINQ
- 部分功能没法在某些平台上使用
- 会分配大量GC Alloc
- 协程Coroutine
- 开启一个协程,至少分配373的内存
-
String链接动画
- 使用StringBuilder或String.Format来代替而不是用”+”来进行链接
关注原则:
-
检测任何一次性内存分配大于2KB的选项
- 检测每帧都具备20B以上内存分配的选项
- GameObject.GetComponet()会引发GC的分配
-
Time
记录了游戏运行时的每帧cpu打败。固然是越小越好,若是占用过大那就找缘由吧。
-
CPU Usage
- WaitForTargetFPS
- vSync功能所致或者帧数限制
- Overhead
- 全部没法统计的时间总和,理论值应该为0.
- Physics.Simulate
- 物理模拟占用的CPU
- Camera.Render
- 相机渲染准备工做的CPU占用量
- RenderTexture.SetActive 设置RenderTexture操做(和相机数一致)
- 比对当前帧与前一帧的ColorSurface和DepthSurface
- 若是一致则不生成新的RT, 不然则生成新的RT,并设置与之相对应的Viewport和空间转换矩阵
- GUI.Repaint
- GUI的重绘,使用的Unity3D自带的GUI,极度不推荐使用
-
Cleanup Unused Cached Data
清空无用的缓存数据,主要包括RenderBuffer的垃圾回收和TextRendering的垃圾回收
-
RenderTexture.GarbageCollectTemporary
存在于RenderBuffer的垃圾回收中,清楚临时的FreeTexture
-
TextRendering.Cleanup
TextMesh的垃圾回收操做
-
-
Application.Integrate Assets in Background
遍历预加载的线程队列并完成加载,同时,完成纹理的加载、Substance的Update等。主要是加载场景的时候会用到,多线程加载
-
AssetBundle.LoadAsyncIntegrate
多线程加载AssetBundle的资源
-
Loading.AwakeFromLoad
在资源加载时会用到,对每种资源进行处理
- WaitForTargetFPS
-
GPU Usage
-
Mesh.DrawVBO
GPU中关于Mesh的Vertex Buffer Object的渲染耗时
-
Shader.Parse
资源加入后引擎对Shader的解析过程
-
Shader.CreateGPUProgram
根据当前设备支持的图开库信息来创建GPU工程
-
-
Profiler须要时刻关注的参数
- CPU—GC Alloc
- CPU—Time
-
MemoryProfiler—Other
-
ManagedHeap.UsedSize
移动游戏建议不超过20M
-
WebStream
经过WWW加载留下的东西,通常会比SerializedFile大得多。包括压缩和解压的东西
-
SerializedFile
经过WWW等方式加载本地的AssetBundle的留下的序列化文件,看是否被卸载掉
-
- MemoryProfiler—Assets
- 查看是否有重复的资源
- Device.Present
- GPU的Presentdevice确实很是耗时,通常出如今使用了很是复杂的Shader等;
- GPU运行的很是快,而因为Vsync的缘由,使得它须要等待较长时间;
- 一样是VSync的缘由,但其余线程很是耗时,因此致使该项等待时间很长,好比过量的assetbundle加载时容易出现该问题
- Shader.CreateGPUProgram
-
StackTraceUtility.PostprocessStackTrace() StackTraceUtility.ExtractStackTrace()
Debug.Log()调试信息形成,这是一个很耗时间的操做。发布的时候尽可能去掉
-
GarbageCollectAssetsProfile
引擎在执行UnloadUnusedAssets操做
-
总结
授人以鱼,不如授人以渔。技术的进步是无止境的,大部分的时候都须要咱们本身去解决问题,只有方法才是真正的解决问题之道。
-
善用、活用Profiler!
- 常用Profiler为项目来进行体验
- 经过Profiler.BeginSample和Profiler.EndSample来自定义检查范围
-
关注CPU & Memory Profiler
- GC Alloc、 Time、 Assets、WebStream…
-