前段时间出的双人成行,让我和对象狗脑子差点打出来,
这不趁着对象睡着了,赶紧来分析一波这游戏的声音系统。
🟥 看看游戏里的声音设置
双人成行的音效设置里面,将所有的声音分为了两块:
- 对话音量
- 音乐音量
并且加上了 “主音量” 选项,总的控制这两个声音的大小。
我们在做项目时,经常也会遇到控制音量的需求,
最基础的做法是查找需要控制的AudioSource,挨个去控制音量。
这样是做最通俗易懂的,但随着不同种类的AudioSource越来越多,控制会变得越来越繁琐。
那下面介绍我们今天的Unity自带工具:Audio Mixer,
来看看是不是可以方便的控制项目音效,优雅的书写代码。
🟧 《双人成行》的音效分析
我们看到双人成行的设置界面,将音效分为:
- 对话音量组
- 音乐音量组
我们再拆分可以分为这几个基础部分:
- 对话音效组
- 背景音乐
- UI音效
- 实体交互音效
- 动物音效
那我们能否有强大的工具, 完成如下功能呢:
- 希望通过一个api,控制整个项目的声音
- 希望分组简单,且可以通过一个api,设置不同组的声音
- 希望方便的拓展新的组或者最底层的音效,且之前写的控制代码会对新的拓展有效
🟨 如何用AudioMixer,分级控制项目音效
我们想实现上面的功能,希望上层控制下层,
一层层向下进行控制。
那树状图,向下分级、分层次的控制,是不是很好的一个解决思路?
我们来看一下根据这个思路,最终建好的AudioMixer:
MasterMixer,是所有音效组的父节点,我们可以控制它的音量,来达到控制全局音量的效果。即所有音效,都受到它自身以上所有父节点的控制,类似Unity的transform。
TalkMixer,是对话音效的组,在MasterMixer之下,受到MasterMixer的控制。
MusicMixer,是音乐组,我们看到下方Groups里有很多音效,音效最上方父物体是Master。那就意味着我们既可以单独控制每个音效的大小,也可以控制Master音量大小,达到控制这个组音量大小的目的。
🟩 项目实战教学
下面我们来实际做一下,如何通过这样的配置,达到控制项目音效的目的。
大家也可以添加文末vx,获得源码工程。
1️⃣ 导入音乐资源
导入我们的音乐资源。
后面我们会通过 Resources 加载播放。
2️⃣ 配置Audio Mixer
🔶 建立Audio Mixer
我们看到上图中的MasterMixer、MusicMixer、TalkMixer,是三个AudioMixer,AudioMixer可在Assets中右键创建。
1️⃣建立AudioMixer:
Assets中AudioMixer的样子:
2️⃣调整节点位置
我们在Assets中建好后,MasterMixer作为根节点,我们要将剩下的两个作为它的子节点。
- 双击MasterMixer打开AudioMixer面板
- 拖动下方的两个AudioMixer到MasterMixer身上去,在弹出的对话框双击Master,完成调整。
3️⃣增加Groups下音效
选中MusicMixer,我们将音效添加进去,注意节点位置!
🔶 暴露Audio Mixer参数
建好了Audio Mixer,代码还不能直接操作。
就像我们的动画状态机一样,我们需要先知道里面的MusicMixer叫什么名字,才能通过代码找到它,对它进行操作。
MusicMixer:
- 每一个音效都是一个MusicMixer。我们的BackgroundMusic、UIMusic、EntityMusic等都是
- 即使是音效组MasterMixer、MusicMixer、TalkMixer,里面也会有一个Master物体。这个物体也是MusicMixer
- 我们最终都是操作这些MusicMixer的属性,达到控制项目音效的效果
因为我们只想控制主音效、对话音量、音乐音量,
因此我们只设置MasterMixer、MusicMixer、TalkMixer这三个音效组的参数就好了。
以MasterMixer为例:
- 选中MasterMixer,点击其内部的Master,
- 在检视面板右击 Volume,选择 Expos xxx to scrip
- 选择Exposed Parameters,将我们刚刚暴露出来的参数,双击命名为“MasterMixer”(谁暴露出来的跟谁同名即可,方便我们找)
其他两个同样的操作,完成参数暴露。
3️⃣ 创建声音播放源AudioSource,并赋值MusicMixer
即在项目中,给这些基础部分声音创建AudioSource,
后面就在这些 AudioSource上,播放对应类别的声音。
Audio Mixer 的使用思路:
- 原先我们播放音频,都是直接 AudioSource.Play 里面的音乐就可以了,camera上面的 Audiolistener 会监听项目中的声音,播放出来。
- 现在,AudioSource 的 output 选项设置了我们的 MusicMixer ,播放声音后,声音受AudioMixer影响,最终输出到 Audiolistener 。
我们控制AudioMixer,即可控制项目不同类别的音量。
1️⃣创建基础声音播放源
因为我们将所有声音分为了对话声音、背景音乐…这五部分,
因此我们创建5个AudioSource,后面就用这些不同的AudioSource播放对应的音乐。
全部取消PlayOnAwake,取消Loop。背景音乐需勾选Loop
UI效果如下:
2️⃣赋值对应的 MusicMixer
下方Assets里拖拽的,就是我们刚才创建的MusicMixer。
将它们拖到对应的位置去即可。
4️⃣ 配置播放音乐面板
🔶 创建UI界面
效果如下图所示:
- 主音量滑动条控制全局音量
- 对话音量控制“对话”的音量
- 音乐音量控制其余音效音量
🔶 编写播放音乐的代码
下面代码用于赋值给左侧按钮,用于点击播放音效。
using UnityEngine; using UnityEngine.UI; public class AudioPlayCon : MonoBehaviour { //赋值我们创建的AudioSource public AudioSource[] audioSources; //赋值我们创建的Btn public Button[] audioBtn; void Start() { audioBtn[0].onClick.AddListener(() => { audioSources[0].clip ??= Resources.Load<AudioClip>("myTalkMusic"); audioSources[0].Play(); }); audioBtn[1].onClick.AddListener(() => { audioSources[1].clip ??= Resources.Load<AudioClip>("myBackgroundMusic"); audioSources[1].Play(); }); audioBtn[2].onClick.AddListener(() => { audioSources[2].clip ??= Resources.Load<AudioClip>("myUIMusic"); audioSources[2].Play(); }); audioBtn[3].onClick.AddListener(() => { audioSources[3].clip ??= Resources.Load<AudioClip>("myEntityMusic"); audioSources[3].Play(); }); audioBtn[4].onClick.AddListener(() => { audioSources[4].clip ??= Resources.Load<AudioClip>("myAnimalMusic"); audioSources[4].Play(); }); } }
5️⃣ 滑动条控制音量改变
现在我们运行游戏,点击左侧按钮,应该可以听到声音了。
那么接下来,我们给上面的滑动条配置代码,做到拖动滑动条,改变音量的效果。
🔶 编写滑动条控制的代码
我们的滑动条,是控制“喇叭”Audio Mixer,输入要控制的参数和数值,
做到控制音效的效果。
using UnityEngine; using UnityEngine.Audio; public class MixerCon : MonoBehaviour { public AudioMixer masterMixer; public AudioMixer musicMixer; public AudioMixer talkMixer; //下方函数使用Dynamic float的方式,赋值给我们的slider // 控制主音量大小 public void SetMasterMixerVolume(float volume) { // MasterVolume为我们暴露出来的Master的参数 masterMixer.SetFloat("MasterMixer", volume); } // 控制说话音量 public void SetTalkMixerlume(float volume) { talkMixer.SetFloat("TalkMixer", volume); } // 控制音乐音量 public void SetMusicMixerVolume(float volume) { musicMixer.SetFloat("MusicMixer", volume); } }
🔶 配置滑动条阈值
因为我们看到MusicMixer的声音阈值,在-80-20分贝之间,
因此我们给滑动条的MinValue和MaxValue,都设置-80、20
🟦 代码思路总结
AudioMixer创建部分:
- 首先,我们将音乐按类别分类成最基础单元MusicMixer
- 接着,再将基础单元分组AudioMixer,我们要控制这些组的音量或音效等
- Assets创建这些AudioMixer组,并在组创建对应的基础单元Group
- 暴露组的参数,供程序调用
UI播放部分:
- 给每个基础单元创建对应的AudioSource,AudioSource的输出属性,赋值这些基础单元。
现在用这些基础单元输出,声音要经过AudioMixer,再由AudioListener输出了 - 播放代码还是老样子,先赋值AudioClip,再GetComponent().Play();
滑动条控制部分:
1、控制的是每个AudioMixer音量大小,即可做到控制项目不同种类音乐大小的目的。
2、子节点AudioMixer受父节点AudioMixer控制。
因为我们的拖拽关系,其余AudioMixer都是MasterMixer的子节点,因此MasterMixer可控制全局音量。
控制代码:
masterMixer.SetFloat("MasterMixer", volume);
该篇文章作为 《GameFramework》 框架的基础知识,
想提升自己,学习Unity框架的可以了解一下 《GameFramework》 ~