提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
提示:这里可以添加本文要记录的大概内容:
一个基于对象池优化思想的音频管理系统,实现了游戏中各种2d和3d不同音效类型播放的需求,包括音效的播放,暂停,继续,停止,播放完成的回调执行等,同时也实现了对音效的开关控制,音量大小控制,以及静音状态的保存。另外采用对象池的优化思想,能够及时对不用的音效组件进行回收利用。
提示:以下是本篇文章正文内容,下面案例可供参考
一、Resource文件夹下的音效片段目录
二、采用单例模式作为全局访问方式
using UnityEngine;
/// <summary>
/// 依赖于Unity Mono的单例,其需要和Unity的一些物体做交互。例如对象池模块和音频管理模块。
/// </summary>
public class MonoSingleton<T> : MonoBehaviour where T : Component
{
private static T _instance = null;
public static T Instance
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType<T>();
if (_instance == null)
{
GameObject obj = new GameObject(typeof(T).Name, new[] {
typeof(T) });
DontDestroyOnLoad(obj);
_instance = obj.GetComponent<T>();
(_instance as IInitable)?.Init();
}
else
{
Debug.LogWarning("Instance is already exist!");
}
}
return _instance;
}
}
/// <summary>
/// 继承Mono单例的类如果写了Awake方法,需要在Awake方法最开始的地方调用一次base.Awake(),来给_instance赋值
/// </summary>
public void Awake()
{
_instance = this as T;
DontDestroyOnLoad(this);
}
}
三、音效类型分类
/// <summary>
/// 音效类型
/// </summary>
public enum SoundType
{
BGM, //背景音乐
UI, //背景音乐
Effect,//效果音
Talk //剧情对话
}
四、播放音效的组件池的数据对象
/// <summary>
/// 音效组件池数据
/// </summary>
[Serializable]
public class ASPoolData
{
[SerializeField] private SoundType _type_;
[SerializeField] private AudioSource _audioSource_;
[SerializeField] private bool _isUseing; //是否在使用中(暂停中属于使用中,因为考虑到还可以继续播放)
[SerializeField] private bool _isInPause;//是否在暂停中
public SoundType Type_ {
get => _type_; set => _type_ = value; }
public AudioSource AudioSource_ {
get => _audioSource_; set => _audioSource_ = value; }
public bool IsUseing {
get => _isUseing; set => _isUseing = value; }
public bool IsInPause {
get => _isInPause; set => _isInPause = value; }
public ASPoolData(SoundType _type, AudioSource _AS, bool _isUsed, bool _isInPause)
{
this.Type_ = _type;
this.AudioSource_ = _AS;
this.IsUseing = _isUsed;
this.IsInPause = _isInPause;
}
}
五、播放时的参数封装
/// <summary>
/// 播放时的参数封装
/// </summary>
public class PlayParams
{
public SoundType type;
public string clipName;
public bool isLoop;
public Action endCallback;//播完的回调
//3d音效
public bool is3d = false;
public Vector3 pos = Vector3.zero;
//2d音效
public PlayParams(SoundType type, string name, bool isLoop = false, Action cb = null)
{
this.type = type;
this.clipName = name;
this.isLoop = isLoop;
this.endCallback = cb;
}
//3d音效
public PlayParams(SoundType type, string name, bool is3d, Vector3 pos, bool isLoop = false, Action cb = null)
{
this.type = type;
this.clipName = name;
this.isLoop = isLoop;
this.endCallback = cb;
this.is3d = is3d;
this.pos = pos;
}
}
六、音效播放管理器
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Collections;
/// <summary>
/// 音效播放管理器
/// BGM不会同时播放多个,不需要使用Audiosource对象池
/// </summary>
public class SoundManager : MonoSingleton<SoundManager>
{
/// <summary>
/// 音效资源路径
/// </summary>
private static readonly Dictionary<SoundType, string> soundPathDict = new Dictionary<SoundType, string>();
/// <summary>
/// 音效播放音量大小
/// </summary>
private static readonly Dictionary<SoundType, float> soundVolumeDict = new Dictionary<SoundType, float>();
/// <summary>
/// 音效的静音状态
/// </summary>
private static readonly Dictionary<SoundType, bool> soundMuteStateDict = new Dictionary<SoundType