目标及介绍
BGM无需3D音效。 实现一个
- 可复用集中管理音效
- 3D多声道
- 播放不冲突
- 可以由制作的音量面板调节(AudioMixer)。
的音效系统。
如何制作音量面板同步控制AudioMixer这里不涉及,从csdn或b站都能找到一大片教学。
遇到的问题
是否3D可以由AudioSource设置播放模式。 play不能同时,会产生冲突。如果设置多个可以但还是违背了“集中管理”? PlayOnShot不能指定位置。 PlayClipAtPoint是静态方法不能由AudioMixer控制。 第四点想可以由AudioMixer调节,只能是确切的AudioSource组件,相应的只能用属于这个AudioSource的对象的成员方法。(目前知识储备是这样理解的,只有成员方法才能由对象的成员变量挂钩,于是无法使用PlayClipAtPoint方法)。
思路
针对1.,可以实现一个AudioManager的空物体并且挂在上AudioManager.cs脚本,所有代码和Clip在AudioManager集中管理。并且AudioManager实现单例模式,多场景可用(DontDestroyOnLoad)。需要时可以直接通过instance单例对象调用相应的方法进行播放。 其实如果不集中管理,在每个音源物体上挂一个AudioSource组件就解决问题了。但是这样对于后续的AudioMixer调整也确实不友好。
针对2.,起初从网上查找教程以为只有PlayClipAtPoint(唯一可以指认音效位置的方法)能播放3D效果。着实不好办了。 后来发现Play和PlayOnShot也可以实现3D音效,本质上是在AudioSource组件把 的SpatialBlend改为就可以实现3D音效了。 然后其他具体的调整可以在3D Sound Settings里进行设置。
针对3.,播放不冲突,那么只能使用PlayOnShot或者PlayClipAtPoint(×)。
针对4.,确保用成员方法,并且有一个AudioSource组件。
一个解决方案
上面写的有点乱。 总之上面每一条限制取一个交集,那么第一时间想到的就是GameObject.Instantiate(gameObject) ,这个gameObject 最好是一个预制体(AudioSpot),上面挂载一个AudioSource组件并且设置为3D音效,并且在其上挂一个AudioSpot.cs,在一定时长之后自动摧毁。这样Play和PlayOnShot都可以用,具体用哪个看代码写法。
这么一来就可以实现这四点要求。
总结
完成了3D多声道、同时、可以受AudioMixer控制的音效系统。
不过当游戏中突发很多音效的时候会不会卡呢?毕竟在瞬时要实例化很多个预制体。不清楚这方面的开销,会不会相当于反向优化游戏呢? 目前知识储备还不太能找到一个完美解决方案,等待后续学习吧。
初入开发Unity,如果这种设计存在缺陷等问题,欢迎留言指正,十分感谢。
|