一、引言
当游戏开发到一个一定的大小的时候,我们会遇到各种各样的问题,其中如何管理音效的播放就是一个非常严重的问题,开枪,走路,跳跃,落地,受伤,死亡,怪物挨打等等等等,各种音效数不胜数,那么此时有一个良好的框架来管理这些音效的播放就再合适不过了,播放的时候只需要调用相关函数,告诉他这是一个什么行为发出的音效,就可以了
二、内容
1.讲解
2.代码
public class AudioSourcePlayManager
{
/// <summary>
/// 单例模式
/// </summary>
private static AudioSourcePlayManager audioSourcePlayManager;
public static AudioSourcePlayManager GetObjectPoolManager()
{
if(audioSourcePlayManager == null)
{
audioSourcePlayManager = new AudioSourcePlayManager();
}
return audioSourcePlayManager;
}
// 保存音效路径和音效文件
private Dictionary<string, AudioClip> sourceManagerDic = new Dictionary<string, AudioClip>();
/// <summary>
/// 获取音效文件位置
/// </summary>
/// <param name="loadPathSFX"></param>
/// <returns></returns>
private AudioClip GetAudioClipSFX(string loadPathSFX)
{
// 检测字典当中有没有
if(!sourceManagerDic.ContainsKey(loadPathSFX))
{
// 没有就添加
sourceManagerDic.Add(loadPathSFX, (AudioClip)Resources.Load(loadPathSFX));
}
return sourceManagerDic[loadPathSFX];
}
/// <summary>
/// 使用对象池音效播放
/// </summary>
/// <param name="loadPathSFX">音效路径 储存在常量中</param>
/// <param name="parentObj">父物体,将音效物体挂载上去</param>
public void PlayAudioSourceSFX(string loadPathSFX, GameObject parentObj)
{
AudioSource audioSource = GenericsObjectPoolManager<AudioSource>.GetObjectPoolManager().CreateObject(parentObj.name, parentObj);
audioSource.GetComponent<Transform>().gameObject.SetActive(true);
audioSource.clip = GetAudioClipSFX(loadPathSFX);
audioSource.Play();
Replace(parentObj.name, audioSource, 0.5f);
}
/// <summary>
/// 不使用对象池的音效播放
/// </summary>
/// <param name="loadPathSFX">音效路径 储存在常量中</param>
/// <param name="audioSource">播放音效的组件</param>
public void PlayAudioSourceSFX(string loadPathSFX, AudioSource audioSource)
{
audioSource.clip = GetAudioClipSFX(loadPathSFX);
audioSource.Play();
}
// 异步编程,延迟0.5秒执行
async void Replace(string parentObjName, AudioSource audioSource, float delayTime)
{
// 等待音效播放完成
// while (audioSource.isPlaying){}
// 异步编程 延迟函数
await Task.Delay(Mathf.RoundToInt(delayTime * 1000));
// 音效播放完成后的操作
GenericsObjectPoolManager<AudioSource>.GetObjectPoolManager().AddObjectPool(parentObjName, audioSource);
audioSource.GetComponent<Transform>().gameObject.SetActive(false);
}
}
3.应用
1.储存音效路径常量的类
public class AudioSourceSFXPath
{
public const string MOUSE_LEFT_BUTTON_DOWN = "Music/SFX/sfx_menu_move1";
public const string MOUSE_RIGHT_BUTTON_DOWN = "Music/SFX/sfx_menu_move2";
}
2.使用,播放
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AudioSourceManager : MonoBehaviour
{
[SerializeField] private GameObject obj;
[SerializeField] private AudioSource audioSourceTest;
private void Start()
{
// 查找摄像机,将音效挂载到摄像机上
obj = GameObject.FindWithTag("MainCamera");
// 获取AudioSource组件
audioSourceTest = GetComponent<AudioSource>();
}
void Update()
{
if(Input.GetKeyDown(KeyCode.Q))
{
AudioSourcePlayManager.GetObjectPoolManager().PlayAudioSourceSFX(AudioSourceSFXPath.MOUSE_LEFT_BUTTON_DOWN, obj);
}
if(Input.GetKeyDown(KeyCode.W))
{
AudioSourcePlayManager.GetObjectPoolManager().PlayAudioSourceSFX(AudioSourceSFXPath.MOUSE_RIGHT_BUTTON_DOWN, obj);
}
if(Input.GetKeyDown(KeyCode.E))
{
AudioSourcePlayManager.GetObjectPoolManager().PlayAudioSourceSFX(AudioSourceSFXPath.MOUSE_RIGHT_BUTTON_DOWN, audioSourceTest);
}
}
}
三、附加
对象池请看我另一篇博客