Unity 工具类 之 简单的背景乐和音频音效管理类实现
Unity 工具类 之 简单的背景乐和音频音效管理类实现
目录
一、简单介绍
Unity 工具类,自己整理的一些游戏开发可能用到的模块,单独独立使用,方便游戏开发。
简单的背景乐和音频音效管理类,单独做了一个单例类,加载管理背景音乐和音频音效,外界单例调用即可。
二、实现原理
1、单例类,保证整个场景中只有一个类管理背景乐和音频音效;
2、文本管理背景乐、音频音效的名称和地址信息;
3、Resources.Load 把对应的背景乐和音频音效加载到字典中,进行管理;
4、AudioManager.Instance.PlayXXX 即可播放对应的背景乐和音频音效;
三、注意事项
1、enum 使用枚举,方便后期调用对应的背景乐和音频音效;
2、文本音频信息,建议使用 json 方便后期查阅;
3、注意Txt格式最好是 utf-8 ,不然可能读不到内容
四、效果预览
五、实现步骤
1、打开Unity,新建工程,向工程中添加背景乐和音频音效,以及音频信息文本,如下图
2、项工程中新建脚本,管理音频音效类,单例类,以及测试音频管理类的脚本,如下图
3、把测试脚本挂载到场景中,如下图
4、运行场景,测试效果如下图
六、代码
1、TestScripts
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestScripts : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0)) {
AudioManager.Instance.PlayAudioEffect(AudioEffectSet.Hit);
Debug.Log("播放音效");
}
if (Input.GetMouseButtonDown(1))
{
AudioManager.Instance.PlayAudioEffect(AudioEffectSet.Click, Vector3.one * 10);
Debug.Log("播放带位置音效");
}
if (Input.GetMouseButtonDown(2))
{
AudioManager.Instance.PlayBGM(BGMSet.ChillMusic);
Debug.Log("播放背景音乐");
}
if (Input.GetKeyDown(KeyCode.Space))
{
AudioManager.Instance.IsMute = !AudioManager.Instance.IsMute;
Debug.Log(AudioManager.Instance.IsMute ? "静音" : "不静音");
}
}
}
2、AudioManager
using UnityEngine;
using System.Collections.Generic;
/// <summary>
/// 音效枚举 (根据文本添加的)
/// </summary>
public enum AudioEffectSet {
Hit,
Bonus,
GameOver,
Click,
}
/// <summary>
/// 背景音乐枚举
/// </summary>
public enum BGMSet
{
ChillMusic,
}
public class AudioManager : Singleton<AudioManager>
{
//音效文本路径
private static string audioTextPathPrefix = Application.dataPath + "/Resources/";
private const string audioTextPathMiddle = "Audio/AudioList";
private const string audioTextPathPostfix = ".txt";
//背景音乐文本路径
private static string BGMTextPathPrefix = Application.dataPath + "/Resources/";
private const string BGMTextPathMiddle = "BGM/BGMList";
private const string BGMTextPathPostfix = ".txt";
private AudioSource BGMAudioSource;
/// <summary>
/// 音效文本文件全路径
/// </summary>
public static string AudioTextPath
{
get
{
return audioTextPathPrefix + audioTextPathMiddle + audioTextPathPostfix;
}
}
/// <summary>
/// 背景音乐文本文件全路径
/// </summary>
public static string BGMTextPath
{
get
{
return BGMTextPathPrefix + BGMTextPathMiddle + BGMTextPathPostfix;
}
}
// 音效字典
private Dictionary<string, AudioClip> audioClipDict = new Dictionary<string, AudioClip>();
// 背景音乐字典
private Dictionary<string, AudioClip> BGMClipDict = new Dictionary<string, AudioClip>();
private bool isMute = false;
/// <summary>
/// 构造函数
/// </summary>
public AudioManager()
{
LoadBGMAndAudioClip();
}
/// <summary>
/// 初始化
/// </summary>
public void Init()
{
}
/// <summary>
/// 是否静音
/// </summary>
public bool IsMute { get => isMute;
set { isMute = value;
// 如果没有 音频源
if (BGMAudioSource == null)
{
BGMAudioSource = Camera.main.gameObject.AddComponent<AudioSource>();
}
if (isMute == true)
{
// 暂停音乐
BGMAudioSource.Pause();
}
else {
// 播放音乐
BGMAudioSource.Play();
}
}
}
private void LoadBGMAndAudioClip() {
audioClipDict = LoadAudioClip(audioTextPathMiddle);
BGMClipDict = LoadAudioClip(BGMTextPathMiddle);
}
/// <summary>
/// 从文本中加载音频数据
/// </summary>
private Dictionary<string, AudioClip> LoadAudioClip(string path)
{
Dictionary<string, AudioClip> audioClipDict = new Dictionary<string, AudioClip>();
// 加载文本数据
TextAsset ta = Resources.Load<TextAsset>(path);
// 解析文本数据内容,并添加到字典中
string[] lines = ta.text.Split('\n');
foreach (string line in lines)
{
if (string.IsNullOrEmpty(line)) continue;
string[] keyvalue = line.Split(',');
string key = keyvalue[0];
AudioClip value = Resources.Load<AudioClip>(keyvalue[1]);
audioClipDict.Add(key, value);
}
return audioClipDict;
}
/// <summary>
/// 播放背景音乐
/// </summary>
/// <param name="name"></param>
/// <param name="volume">音量</param>
/// <param name="isLoop">循环与否</param>
public void PlayBGM(BGMSet name, float volume = 0.5f, bool isLoop = true) {
// 如果静音,则不播放声音
if (IsMute) return;
if (BGMAudioSource == null) {
BGMAudioSource = Camera.main.gameObject.AddComponent<AudioSource>();
}
// 设置背景音乐音量和循环与否
BGMAudioSource.Stop();
BGMAudioSource.volume = volume;
BGMAudioSource.loop = isLoop;
// 从字典中获取对应音效进行播放
AudioClip ac;
BGMClipDict.TryGetValue(name.ToString(), out ac);
if (ac != null)
{
BGMAudioSource.clip = (ac);
BGMAudioSource.Play();
}
}
/// <summary>
/// 播放音效
/// </summary>
/// <param name="name">音效名称</param>
public void PlayAudioEffect(AudioEffectSet name)
{
PlayAudioEffect(name, Vector3.zero);
}
/// <summary>
/// 带位置播放音效
/// </summary>
/// <param name="name">音效名称</param>
/// <param name="position">位置</param>
public void PlayAudioEffect(AudioEffectSet name, Vector3 position)
{
// 如果静音,则不播放声音
if (IsMute) return;
// 从字典中获取对应音效进行播放
AudioClip ac;
audioClipDict.TryGetValue(name.ToString(), out ac);
if (ac != null)
{
AudioSource.PlayClipAtPoint(ac, position);
}
}
}
3、Singleton
public abstract class Singleton<T> where T : class, new()
{
private static T instance = null;
// 多线程安全机制
private static readonly object locker = new object();
public static T Instance
{
get
{
lock (locker)
{
if (instance == null)
instance = new T();
return instance;
}
}
}
}
4、AudioList.txt
Hit,Audio/Hit
Bonus,Audio/Bonus
GameOver,Audio/GameOver
Click,Audio/Click
5、BGMList.txt
ChillMusic,BGM/ChillMusic