前几天去北京参加了unite2014大会,举办的还不错。老外来的都是引擎的开发程序员,所以他们讲的内容基本都是unity5的一些新技术,讲解过程有同声传译,不过有些技术词汇不翻译还听得懂一点(今年得练英文口语和听力了,希望下次能直接和老外交流)。国内的技术专家讲的内容更贴近开发一些,一些优化相关的内容还是非常有帮助的。
开始以为参会的可以下载讲师的ppt,所以没有进行太多的记录,只有些零散的笔记,而且我一个人也只能听完一半的技术讲座。下面就是稍微整理了一下的笔记:
Unity开发四大准则
1. 美术资源量对于程序发布包的大小、性能优化、内存占用量的影响,往往超过其他种种因素。
技术美术和关卡设计师对于游戏性能承担着重要的责任;
程序员往往无法补救由于滥用美术资源而造成的性能问题;
2. 项目团队应该通过编写工具来保证美术资源的合法性。
美术规范文档无法再实际上保证美术资源的合法性;
程序员应该通过Unity编辑器扩展技术,为美术师实现完整的美术资源合法性检查工具;
3. 对渲染效率和内存占用的优化应该在项目实施过程中反复进行。
针对CPU/游戏逻辑的的优化往往能够比针对GPU/Shader的优化取得更大的做用;
GPU/Shader的性能优化应该放在最后进行;
善用UnityProfilers;
4. 从反向工程的角度理解项目开发,以最终需要达到的目的来决定程序的架构设计以及关键技术的方案选择。
是否需要进行代码的增量更新;
是否需要严格控制程序发布包的大小;
是否需要支持低端移动设备等等;
手游资源优化
贴图尽量合并;
使用substance texture减少资源量;
字体颜色和一些效果可以用shader来实现;
尽量减少mesh数据;
可能的话使用lod;
尽可能利用dynamic batching和staticbatching减少draw call;
控制骨骼数量和骨骼影响的顶点数;
所有的角色动画放在一个文件中;
优化动画关键帧;
音频,视频控制质量;
避免实时计算的东西;
Texture
Use GPU friendly texture(ETC1, ETC2, ASTC)
Build for specific GPU(DTX, PVRTC, ATC)
Build Atlas when possible(with/withtoualpha)
Use Sustance procedural texture
Use Unity Dynamic Texture
Runtime Creation/ Altas Packing /Compression
Font
Use TTF instead of Texture
Remove unused character from TTF files
Use Native Font(Android 2.3/4.1)
Add Shader Effect(Colorize/Outline)
Shader
Use build-in Unity 'mobile' shader
Build full custom shader per GPU
Reduce number of instruction
Reduce the number of texture fetch
ToAvoid .. Expensive
function: pow, exp, log, cos, sin, tan
custom operation: normalize, dot,inverseqrt
'Discard' fixed function(Alpha Test)
'ColorMask' render setup that turn off channel render
Reflection
Fog
Float Precision
Use smallest float precision when possible
float/highp : 32-bit(vertex shader, for vertex transformation)
half/mediump :16-bit(texture UV coordinates)
fixed/lowp :10-bit(color, unit length vector, light calculation)
DynamicBatching
Dynamic Batching(on moving object)
Apply automaticly
withLess than 900 vertex(VBO)
with Same Material
with Same Uniform Scale/Different Non-Uniform Scale
without Multi-Pass Shaders
without Receiving real-time shadows
StaticBastching
Static Batching(on non-moving object)
Require additional memory
with 'Mesh Renderer' or 'Particle Renderer'(not GUI)
Canbe mark on non-moving mesh part that have animation
Combine static mesh inside the samemesh(sub-mesh)
Skinning
Reduce number of bone in skinned mesh
Only keep bone in hierachy that will affectthe skinning
Reduce number of bone influence per vertex
Aniamtion
Merge animation using the same hierachy in one FBX
Use same animation on multiple skinned object
Bled animation(Mecanim Animation System)
KeyReduction
Post-Process in Unity or Pre-Process In FBX
Audio
Force to Mono/Decrease kbps
Uncompress WAV & Compress MP3 case
Uncompress (shortClip/SoundFX)
Compressed in Memory (Longer/Looping clip)
Stream form disc (Music)
Decompress on load (Clipcausing CPU process spike)
Require additional memory
Video
Create Cut-Scene instead of Cinematic
Convert into Theora OGG format
Reduce kbps(use different quality for Video/Audio)
Light
Avoid Real-Time lighting
use lightmap..(increase APK size & decrease Performance)
if needed, use a maximum of 1 directional light
Avoid Real-Time shadow
use texture shadow instead
性能问题
对Profiler的分析需要贯穿于整个项目开发期。
弄清每一个参数的含义;
如果GC相关函数时间长,会造成“顿卡”,查看内存分配,注意每帧会产生的堆内存分配;
AssetBundle要进行依赖打包,否则会造成包和内存都增大;
目前官方自带的GUI占用内存大、效率低;
Poolmanager是很有用的内存和对象管理插件;
(华为某芯片对shader解析非常慢)
优化局部代码:
使用Profiler.BeginSample()和Profiler.EndSample();
C#一些高级功能会造成额外的内存分配(foreach、LINQ、Lambda表达式等);
String连接使用StringBuilder;
Get相关函数会造成查找,尽量避免在Update内直接调用;
一些插件也有可能造成内存分配问题;
将代码包含在下载包内
参看官方文档Included scripts in AssetBundles。
代码增量更新
原理:Unity脚本经过编译后就不能再修改,但是可以添加
方案2:将接口与实现分离
不改变用户工作流程
仍可在编辑器中使用动态编辑
对代码起到一定的保护作用(可以混淆)
对原有的AssetBundles打包方案没有任何影响
(代码打包不适合iOS,因为不支持反射)
ResourcesVS Assetbundle
Resources 加载快,内存占用少,无法更新,文件夹里有2G的限制
Assetbundle动态加载,内存占用大
如何使用
一些不变的资源用Resources
变的用Assetbundle
开发版本用Resources,发布版本用Assetbundle
创建AssetBundle的选项
CollectDependencies 包含所有的依赖的Assets
CompleteAssets 包含Object所属的Asset的所有Objects
DisableWriteTypeTree 不写入TypeTree
DeterministicAssetBundle每个Object有唯一的内部ID,适用于增量式打包AssetBundle
UncompressedAssetBundle不进行数据压缩
依赖关系打包
比如有2个包中都含有mat,则需要将mat单独打成1个包,参看官方文档Managing asset dependencies相关内容。
如何获取资源依赖关系
Assetdatabase.GetDependencies
分析资源依赖关系
统计输出没必要的资源
AssetBundle发布方式
1. AssetBundle进安装包
压缩格式
把AssetBundle放到SteamingAssets目录下
WWW加载
2. AssetBundle不进安装包(单独下载)
非压缩格式或压缩格式
制作一整个压缩文件(7z或zip)
下载解压
CreateFromFile加载或WWW
加载
Build输出的依赖关系文件(xml,json等)
建议一个队列,Sheduler类进行调度加载
被依赖的assetbundle要等到上层assetbundle加载完才可以unloadassetbundle(false)
释放
在切换场景时,释放GameObjet,资源引用置为null,释放assetbundle。
AssetBundle.Unload(true)
调用Resources.UnloadUnusedAsests
异步
一些有用的插件:
加载优化Poolmanager5,优化资源加载和管理,优化gc
测试插件Unity Test Tool(本次有作为单独讲座讲解,可惜我没有参加)
游戏分享Everyplay
动画finalIk
运行时效率统计FpsGraph
杂项:
Unity5会做新的AssetBundle系统;
会增加UNet(这个我只听了一点,不知道架构和photon引擎是不是类似的,似乎也是有cloud服务器的)