在游戏中,都需要播放声音与视频,其中声音又可以分为音乐和音效两种。

音乐就和背景音乐一样,一直在循环播放;

而音效用得就更多了,例如释放技能、被攻击所带来的声音,而且音效很可能同时需要播放好几组。

为了满足更加逼真的效果,Unity提供了强大的回音模式以及3D音频模式,如果远处和近处都有音效,听起来真实。

另外,Unity提供Audio Mixer组件,在编辑模式下使用它来组合播放各种声音以及混合播放多音频。

新版的视频功能既可以将视频输出在摄像机的前面或后面,也可以将视频放在UI以及场景中间,还可以将视频材质输出并自定义渲染在贴图上。

音频文件

音频由多个Audio Source组件和一个Audio Listener组件组成,其中Audio Listener负责监听所有的Audio Source,最终通过扬声器播放出来。如果是3D音效,Unity会自动判断Audio Listener与Audio Source的距离,从而增强或者减少音量。

同一个场景只能有一个Audio Listener组件启用,它默认添加在主摄像机上

Unity支持的音频文件非常丰富,他们包括.mp3、.ogg、.wav、.aiff、.aif、.mod、.it、.s3m、.xm,其中最常用的就是.mp3和.ogg声音文件了。

我们将一个.mp3文件拖入Project视图中。我们可以单独设置声音文件是否在后台加载,以及声音文件的压缩格式等。

音频剪辑 - Unity 手册 (unity3d.com)

这些设置会让Unity在打包后将原始的音频转换成一个更适合游戏的新的音频,我们在编辑器模式下可以预览设置后的音频效果

音频导入设置

Audio Source

给任意对象绑定Audio Source组件,即可播放声音。将音频文件绑定在Audio Clip处,再选中Play On Awake和Loop复选框,就可以循环播放声音了。

Audio Source组件

音频源 - Unity 手册 (unity3d.com)

3D音频

3D音频就是根据声源与主角的距离自动调节音频。由于Audio Listener是绑定在主摄像机上的,控制摄像机的远近即可满足3D音频。

默认情况下Audio Source是2D音频。根据上图的参数,调节Spatial Blend,可以设置2D和3D音频的比例。

Priority表示声音的优先级。同时播放的音频是有最大上限的,超过后会自动关闭优先级最低的音频(0是最高级),所以背景音乐一类适合设置为0,。

Volume表示声音的音量、Pitch表示音频的播放速度,Stereo Pan表示左声道和右声道占比,Reverb Zone Mix用于设置回音混合。

开启3D音频后,就可以调节最小距离以及最大距离了。在scene窗口中可以通过两个球形区域表示3D声音最大区域和最小区域,可以直接在scene中修改也可以在面板中设置。角色在最小音频区域内听到的音量最大,在最小区域与最大区域听到的音量递减,当角色超出最大区域时,会保持递减后最小的音量。

运行游戏,直接移动场景中的摄像机,即可听到效果。

音频范围

代码控制播放

在代码中获取Audio Source组件,就可以动态控制音频了,由于音频组件没有播放音频结束的回调,所以可以先获取音频的播放时间,接着通过添加定时器来等待音频播放结束,然后再处理结束后的事件。

新建PlayAudio脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class PlayAudio : MonoBehaviour
{
public AudioClip clip1, clip2;
public AudioSource source;

private void OnGUI()
{
if (GUILayout.Button("<size=50>播放音频1</size>"))
{
PlayAudioClip(clip1, clip =>
{
Debug.LogFormat("音频:{0}播放结束",clip.name);
});
}
if (GUILayout.Button("<size=50>播放音频2</size>"))
{
PlayAudioClip(clip2, clip =>
{
Debug.LogFormat("音频:{0}播放结束", clip.name);
});
}
}
private Coroutine m_Coroutine = null;
private void PlayAudioClip(AudioClip clip,UnityAction<AudioClip> callback)
{
StopAudioClip();
source.clip = clip;
source.Play();
m_Coroutine = StartCoroutine(AudioClipCallback(clip, callback));
}
private void StopAudioClip()
{
if(m_Coroutine != null)
{
StopCoroutine(m_Coroutine);
m_Coroutine = null;
}
}
private IEnumerator AudioClipCallback(AudioClip clip,UnityAction<AudioClip> callback)
{
yield return new WaitForSeconds(clip.length);
callback.Invoke(clip);
}
}

clip.length用于获取音频的长度(秒),yield return new WaitForSeconds()等音频播放完毕后抛出事件

混音区

使用Audio Reverb Zone组件,就可以实现混音效果,其中有很多预设参数,也可以设置最大区域和最小区域。

新建个空对象,然后挂载Audio Reverb Zone组件,从摄像机监听即可

 Reverb Zone

Audio Reverb Zone组件

Audio Mixer

音效混合器就是同时将多个音频文件混合播放,可以调节混合参数以及添加音频特效。

在Asset中添加Audio Mixer,然后双击或者Window——Audio——Audio Mixer面板。我们在Group中点击加号,为Master添加两个子Group。

Audio Mixer

在场景中添加多个Audio Source,每个音频可以根据需要output到不同的Audio Mixer Group当中

Output

根据音频Group的树形结构,Master应用的音量和音效都会应用到它的子级,Master应用S(独奏)、M(静音)、B(取消所有音效)也都会影响到子级。

Group可用来分离音效设置(主音量、语音音量、音效音量)

Snapshots可以设置音效快照,选中一个的情况下修改各个group的音效参数,然后新建一个snapshot再修改参数,就能分别记录,有助于我们快速切换试听不同音效调试效果

View可以设置视图快照,记录每一个group之前的“眼睛”,记录每一个group的开闭情况。添加View可以快速开闭一些Group

录音

Unity提供了录音接口。只要硬件支持,就可以进行录音

新建RecordVoice脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using UnityEngine;

public class RecordVoice : MonoBehaviour
{
public AudioSource source;
public AudioClip m_Clip;
void Start()
{
if (Microphone.devices.Length !=0)
{
source.clip = Microphone.Start(Microphone.devices[0], true, 10, 44100);
source.Play();
}
}

private void OnGUI()
{
if (GUILayout.Button("<size=50>开始录音</size>"))
{
m_Clip = Microphone.Start(Microphone.devices[0], true, 10, 44100);
//foreach (var device in Microphone.devices)
//{
// Debug.Log(device);
//}
}

if (GUILayout.Button("<size=50>结束录音</size>"))
if (m_Clip)
Microphone.End(Microphone.devices[0]);
if(GUILayout.Button("<size=50>播放保存录音</size>"))
if (m_Clip)
{
source.clip = m_Clip;
source.Play();
}
}
}

录音

声音进度

我们通过拖动Slider来调节音乐的进度。在代码中监听Slider拖动的值,可以动态更新音乐开始播放的位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using UnityEngine;
using UnityEngine.UI;

public class AdjustAudioProgress : MonoBehaviour
{
public Slider slider;
public AudioSource source;
void Start()
{
slider.maxValue = source.clip.length;
slider.minValue = 0;
slider.onValueChanged.AddListener(value =>
{
source.Stop();
source.time = value;
source.Play();
});
source.Play();
}
}