Unity的音频设置中有好多平时不会去了解的属性,本文只从How to而不是Why的角度整理一下可用的优化方式。
3D音效使用Force to Mono
立体声有左右两个省道,大小和内存占用都会翻倍。但是Unity中两个声道都是从同一个点发出,双声道没有意义。
最佳实践:
如果使用了双声道的音源,可以通过勾选Force to Mono轻松将双声道音源变成普通音源,节省内存开支。
使用正确的加载类型和压缩格式
关于压缩类型
- Decompress on Load – 解压完整的数据进内存
- Compressed in Memory – 加载进内存,使用的时候解压。用CPU性能换一部分内存。
- Streaming – 完全不加载进内存,使用时从存储介质中串流。最省内存,消耗最多CPU。
下图为同一声音文件在默认压缩格式下使用3种不同加载类型的CPU和内存消耗:
关于压缩格式
在使用Decompress on Load时,压缩格式对内存没有影响(因为无论如何都是会解压后进内存的),但是对包体大小会有影响。使用PCM会增加包体大小,而使用Ogg Vorbis包体会更小,但是在加载进内存时需要解压缩,不过解压缩的消耗可以忽略不计。
在使用Compressed in Memory时,如果你想要通过Quality选项进一步压缩声音文件的质量和大小,使用Ogg Vorbis会更好。但是在同样100% Quality的情况下,ADPCM占用的内存比Ogg Vorbis更小,而且解压缩消耗的CPU资源比Ogg Vorbis小很多。不过,无论如何不要使用PCM,因为PCM是不压缩的格式,完全没有利用上Compressed in Memory的优势。
在使用Streaming时,和Compressed in Memory类似,使用ADPCM可以节省很多CPU资源。不同的是,可以使用PCM进一步节省CPU资源,因为PCM没有压缩。PCM唯一的缺点是会占用更多的存储资源。
MP3格式相较上述格式没有显著优势,因此不用考虑。
另外,需要注意的是,在移动端短时间内Stream多个声音文件可能会造成CPU的高负载。
最佳实践:
- 时间短的音效使用Decompress on Load,压缩格式使用Ogg Vorbis
- 时间较长的音效使用Compressed in Memory,压缩格式使用ADPCM
- 音乐(如背景音)使用Streaming,压缩格式使用PCM
声音数量限制和优先级
Unity默认的声音数量限制是32个,但可以通过设置更改
Real Voice是指真正能听到的声音数量。假如限制为1,则无论什么时候都只能听到1个声音,其他声音会根据优先级依次变为Virtual Voice。
Virtual Voice会在后台继续播放,但实际听不到。当Real Voice小于设定的上限时,Virtual Voice会根据优先级变成Real Voice继续播放。如果Virtual Voice数量大于设置的上限时,会根据优先级被停止。
每个声音都可以设置优先级,0为最高,256为最低:
最佳实践:
- 尽量保持默认设置。如果需要提高上限,手机上Max Real Voices最好低于40,高端手机低于60;主机、桌面端低于80。
- Max Virtual Voices大于Max Real Voices
- 大部分声音都使用一样的优先级,少数重要的声音设置高优先级
暂停不使用的声音
如果Max Real Voices设置的不高,这个方法没有必要。如果设置了较高的声音数量上限,则有必要手动暂停一些在AudioListener以外的声音。只需要给所有带声音的物体挂上如下脚本即可:
1 | using System.Collections; |
非必须的音效勾选Load in Background
勾选此选项后,Unity在加载场景时不会等待该声音完全加载好,可以减少加载场景的时间。下图是在加载场景时加载约90个音频和大量Prefab时,勾选和不勾选Load in Background的对比。不是很精确的实验,但是有参考作用:
最佳实践:
在加载一些场景初始阶段非必需的声音(如怪物死亡音效、胜利音效等)时,可以勾选此选项。
合理加载音频数据
Unity导入音频时有个默认勾选的选项为Preload Audio Data,即在加载声音文件时,同时将声音的信息(如时长)和音频数据加载进内存。如果不勾选,则只有声音信息会被加载进内存。
因此,如果不勾选此选项,可以节省一些内存,但是需要在使用该声音时手动加载:
1 | audioClip.LoadAudioData(); |
为了节省内存,也可以手动卸载该声音:
1 | audioClip.UnloadAudioData(); |
最佳实践:
手动卸载不需要使用的音频数据,在需要时重新加载
禁用音频组建而不是使用静音
当音频组件还被挂在物体上时,就算使用了静音,也依然存在相关的性能开销(如计算声音和Audio Listener)之间的距离。因此,如果不是真的有“静音”这个需求,尽量禁用音频组件,搭配上一段落的卸载音频数据效果更佳。