目录
前言
建立音频配置文件AudioConfig
建立音频管理AudioManager
使用AudioManager播放音效
前言
关于音频组件的简单使用请详见VideoPlayer&AudioSource,不过在一个工程项目中,会有很多的声音文件,播放的时间和条件也不相同,因此在实际制作中,需要集中管理,这就是建立AudioManager的原因。
先做好准备,下载好需要的声音片段,这里准备了背景音效bgm和走路音效step,存放到Assets/Resources/Audio文件夹下
建立音频配置文件AudioConfig
1. 创建一个AudioConfig.cs脚本:
[CreateAssetMenu(fileName = "AudioConfig", menuName = "tang/AudioConfig", order = 1)]
public class AudioConfig : ScriptableObject //继承这个类,会将配置文件作为唯一的实例保存
{
public string audioPath = "Audio/"; //音频的总路径,在Resources/Audio下
[Range(0, 1)]
public float mainVolume = 1; //主音量
[Range(0, 1)]
public float effectVolume = 1; //音效音量
[Range(0, 1)]
public float bgmVolume = 1; //背景音乐音量
public List<AudioData> audioLibrary;
}
说明:(1)CreateAssetMenu用于在Project窗口中点右键的菜单中生成一个自己命名的菜单,这里生成一个AudioConfig菜单,用于配置AudioConfig类中的参数
(2)ScriptableObject类,用于存储配置数据,详见ScriptableObject使用指南_YY-nb的博客
2. AudioConfig类中的AudioData,定义了音效的设置参数,可以直接写在AudioConfig.cs脚本中:
[Serializable] //将AudioData序列化,以便于在面板中看到
public struct AudioData
{
//通过字符串找到相应的声音片段
public string key;
//音频资源文件
public AudioClip clip;
//音量控制属性
[Range(0,1)]
public float volume;
//音频类型
public EAudioType type;
}
3. AudioData中的类型EAudioType,是一个枚举类型,定义了音效的类型,比如背景音效、跑步音效等
public enum EAudioType
{
BGM,EFFECT
}
4. 这样,在右键->tang->AudioConfig之后,就可以新建一个声音配置文件,在它的管理列表中点“+”号就可以添加一个新的音效片段的管理数据,这些数据将被放入AudioManager的字典中随时调用。
建立音频管理AudioManager
在这里要设置对于背景音效、效果音等不同类型音的:播放、停止、调整音量等一些实用工具,根据项目的需要还可以设计一些其他的实用工具。这些都写在AudioManager.cs中,这是一个管理阶层的工具,同样继承于SingleMono单例,挂在场景中的SingleMono空节点上。
1. 先定义一下管理中需要使用到的参数:建立一个播放背景音的声音源和一个播放音效的声音源,建立音量参数,以及一个字典用于存储声音片段及相关的数据:
public class AudioManager : SingleMono<AudioManager>
{
public AudioSource bgmSource; //背景音声音源
public GameObject effectSource;//音效声音源
public AudioConfig audioConfig; //声音配置文件,自定义
[Range(0, 1)] private float mainVolume = 1; //总的音量,规定取值范围
[Range(0, 1)] private float effectVolume = 1; //音效音量
[Range(0, 1)] private float bgmVolume = 1; //背景音乐音量
//定义一个字典用于存储音效名及需要传输的数据
private Dictionary<string, AudioData> audioLibrary;
void Awake()
{
audioLibrary= new Dictionary<string, AudioData>();
foreach(var data in audioConfig.audioData)
{//遍历一下audioConfig中的audioData列表
//将列表中的所有数据加入到字典中
audioLibrary.Add(data.key, data);
}
mainVolume = audioConfig.mainVolume; //把在面板中设置的音量值加载进来
effectVolume = audioConfig.effectVolume;
bgmVolume = audioConfig.bgmVolume;
}
}
这需要在场景中设置两个空节点,bgmSource和effectSource,bgmSource中加入AudioSource组件,effectSource节点空着。并将它们和上面的AudioConfig文件拖入到相应的三个public变量中:
2. 加入播放BGM的一些工具,这里只是列举了一些,当需要其他的BGM控制工具时再来增加:
//播放背景音效
public void PlayBGM(string key, bool isLoop, Action onComplete = null)
{//通过key找到字典中相应的数据,是否循环,播放完毕后回调
AudioData data;
if (!audioLibrary.TryGetValue(key, out data))
{//字典中没有找到该key
Debug.LogError("音频:" + key + "播放出错!");
return;
}
float volume = mainVolume + data.volume + bgmVolume;//最终音量
//使用AudioSource的API设置并播放音效
bgmSource.clip = data.clip;
bgmSource.loop = isLoop;
bgmSource.volume = volume;
bgmSource.Play();//使用AudioSource的API-Play()播放音效
}
//使用AudioSource的API暂停和取消暂停
public void PauseBGM()
{
bgmSource.Pause();
}
public void unPauseBGM()
{
bgmSource.UnPause();
}
public void changeBGMVolume(float volume)
{//修改音量值,传入一个音量系数
bgmSource.volume = bgmSource.volume / bgmVolume * volume;
bgmVolume = volume;
}
public void ResetBGMVolume()
{//重置音量
bgmSource.volume = bgmSource.volume / bgmVolume * audioConfig.bgmVolume;
bgmVolume = audioConfig.bgmVolume;
}
public void StopBGM(Action onComplete = null)
{//停止播放
bgmSource.Stop();
bgmSource.clip = null;
onComplete?.Invoke(); //回调
}
3. 加入播放其他音效的一些办法,也包括了上面这些方法,有所不同的是,背景音乐同时播放的只有一个,而音效可能会播放多个。因此音效的AudioSource组件需要动态添加,需要播放几个音效就要添加几个组件:
public AudioSource PlayEffect(string key, bool isloop)
{//播放音效
AudioData data;
if (!audioLibrary.TryGetValue(key, out data))
{
Debug.LogError("音频:" + key + "播放音效出错!");
return default;
}
float volume = mainVolume * data.volume * effectVolume;//最终音效音量计算
//音效有可能会同时播放多个,所以AudioSource组件有可能加载多个
AudioSource[] sources = effectSource.GetComponents<AudioSource>();
//是否找到空闲的AudioSource组件
bool bTmp = false;
foreach(var audios in sources)
{
if(!audios.isPlaying) //如果这个AudioSource不在播放状态
{
audios.clip = data.clip;
audios.loop = isloop;
audios.volume = volume;
bTmp = true; //将判断改为在用状态
audios.Play(); //开始播放音效
return audios; //播放完成之后,将值返回出去
}
}
if (!bTmp)
{
var source = effectSource.AddComponent<AudioSource>(); //如果没有找到空闲的AudioSource则增加一个
source.clip = data.clip;
source.loop = isloop;
source.volume = volume;
source.Play();
return source;
}
return default;
}
使用AudioManager播放音效
定义一个Test.cs随意挂在场景
public class Test : MonoBehaviour
{
// 播放音频
void Start()
{
AudioManager.Instance.PlayBGM("BGM", true); //播放背景音效
}
void Update()
{
if (Input.GetKeyDown(KeyCode.T)) //按下T键时播放音效
{
AudioManager.Instance.PlayEffect("Step", false);
}
}
}
相应的AudioConfig设置:
效果就不放了,声音播放也没有办法展示。