音效模块

音效系统

1.个人思路

  • 1.情景假设

一天,小明想听歌。于是,他拿起手机,找到音乐播放软件,选择歌曲,按下播放键,听到了想听的歌

  • 2.过程分析

1 小明想听歌 -> 听歌的对象,歌曲信息接收者

2 打开音乐播放软件 -> 播放音乐的对象,音效源

3 选择歌曲 -> 选择的数据,音效资源

  • 3.实现思路

AudioListener: 音效的监听者

AudioSources:音频控制器

AudioClip:音频文件

2.代码实现

2.1 简易播放器

`using UnityEngine;

// 添加音效源
[RequireComponent(typeof(AudioSource))]
public class AudioManagerA : MonoBehaviour{

public AudioClip AudioClip;
private AudioSource _audioSource;

private void Start()
{
_audioSource = GetComponent();
}

// 播放音效
public void PlayAudio(float volume = 1.0f, bool isLoop = false)
{
_audioSource.clip = AudioClip;
_audioSource.volume = volume;
_audioSource.loop = isLoop;
_audioSource.Play();
Debug.LogFormat("播放音效: {0}", AudioClip.name);
}
}`

`using UnityEngine;

public class TestA : MonoBehaviour {

public bool IsPlayAudio;

void Start () {
gameObject.AddComponent();
// 选择播放的音效
gameObject.GetComponent().AudioClip = Resources.Load("Audio/BackgroundMusic/BgMusic");
}

void Update () {
if (IsPlayAudio)
{
IsPlayAudio = false;
gameObject.GetComponent().PlayAudio();
}
}
}`

2.2 如何方便的选择音效文件

` using System;
using System.Collections.Generic;
using UnityEngine;

public interface IUploadAudio
{
// 加载音效资源
AudioClip GetAudioClip(string audioName);
}

[RequireComponent(typeof(AudioSource))]
public class AudioManagerB : MonoBehaviour, IUploadAudio {

// 保存已经加载过的音效
private Dictionary<string, AudioClip> _audioDict;
private AudioSource _audioSource;

private void Start()
{
_audioDict = new Dictionary<string, AudioClip>();
_audioSource = GetComponent();
}

// 播放音效
public void PlayAudio(string audioName, float volume = 1.0f, bool isLoop = false)
{
if (!_audioDict.ContainsKey(audioName))
{
_audioDict.Add(audioName, GetAudioClip(audioName));
}
_audioSource.clip = _audioDict[audioName];
_audioSource.volume = volume;
_audioSource.loop = isLoop;
_audioSource.Play();
}

public AudioClip GetAudioClip(string audioName)
{
AudioClip audioClip = Resources.Load(audioName);
if (audioClip == null)
{
throw new Exception("没有找到相应的音效资源 请确认路径:" + audioName);
}
return audioClip;
}
}`


`using UnityEngine;

public class TestB : MonoBehaviour {

public bool IsPlayAudio;
public string AudioName;

void Start()
{
AudioName = "Audio/BackgroundMusic/BgMusic";
gameObject.AddComponent();
}

void Update()
{
if (IsPlayAudio)
{
IsPlayAudio = false;
gameObject.GetComponent().PlayAudio(AudioName);
}
}
}`

2.2.1 使用一个音效路径管理类

`public class AudioPath
{

public const string BACKGROUND_MUSIC = "Audio/BackgroundMusic/BgMusic";
public const string BACKGROUND_MUSIC_B = "Audio/BackgroundMusic/BgMusicB";
public const string BACKGROUND_MUSIC_C = "Audio/BackgroundMusic/BgMusicC";
public const string BACKGROUND_MUSIC_D = "Audio/BackgroundMusic/BgMusicD";

}`

2.2.2 使用枚举组装路径

`public class AudioType {

public enum Dialogue
{

}

public enum ScreenOnClick
{
// 点击正确
Correct,
// 点击错误
Error,
}

public enum SpecialEffects
{

}

public enum BackgroundMusic
{
// 背景音乐
BgMusic,
}

public enum Other
{

}
}`


`using UnityEngine;

public class TestB : MonoBehaviour {

public bool IsPlayAudio;

void Start()
{
gameObject.AddComponent();
}

void Update()
{
if (IsPlayAudio)
{
IsPlayAudio = false;
gameObject.GetComponent().PlayAudio(AudioType.BackgroundMusic.BgMusic);
}
}
}`


`using System;
using System.Collections.Generic;
using UnityEngine;

public interface IUploadAudio
{
// 加载音效资源
AudioClip GetAudioClip(Enum audioName);
}

[RequireComponent(typeof(AudioSource))]
public class AudioManagerB : MonoBehaviour, IUploadAudio
{

// 保存已经加载过的音效
private Dictionary<Enum, AudioClip> _audioDict;
private AudioSource _audioSource;
private const string audioPath = "Audio/";

private void Start()
{
_audioDict = new Dictionary<Enum, AudioClip>();
_audioSource = GetComponent();
}

// 播放音效
public void PlayAudio(Enum audioName, float volume = 1.0f, bool isLoop = false)
{
if (!_audioDict.ContainsKey(audioName))
{
_audioDict.Add(audioName, GetAudioClip(audioName));
}
_audioSource.clip = _audioDict[audioName];
_audioSource.volume = volume;
_audioSource.loop = isLoop;
_audioSource.Play();
}

public AudioClip GetAudioClip(Enum audioName)
{
string audioType = audioName.GetType().Name;
AudioClip audioClip = Resources.Load(audioPath + audioType + "/" + audioName);
if (audioClip == null)
{
throw new Exception("没有找到相应的音效资源 请确认路径:" + audioName);
}
return audioClip;
}
}`

2.3 考虑多个播放源

2.3.1 接口设置

`public interface IUploadAudioClip
{
// 加载音效资源
AudioClip GetAudioClip(Enum audioName);
}

public interface IUploadAudioSource
{
// 加载音效播放源
AudioSource GetAudioSource(string audioSourceName);
}

public interface IPlayAudio
{
// 播放音效
void PlayAudio(Enum audioName, float volume, bool isLoop, string audioSourceName);
// 停止播放的音效
void StopAudio(string audioSourceName);
}`


2.3.2 播放源系统

`
public class UploadAudioSourceStrategy : IUploadAudioSource
{
// 播放的音频源
private Dictionary<string, AudioSource> audioSourceDict;
// 音效管理器
private GameObject audioControl;
private static int count;
private readonly string currentAudioName;

public UploadAudioSourceStrategy()
{
audioSourceDict = new Dictionary<string, AudioSource>(3);
audioControl = new GameObject { name = "AudioModuleControl" };
Object.DontDestroyOnLoad(audioControl);
audioControl.AddComponent();
}

public AudioSource GetAudioSource(string audioSourceName)
{
if(audioSourceName.Equals(string.Empty))
{
return GetCurrentAudioSource();
}

if (audioSourceDict.ContainsKey(audioSourceName))
{
return audioSourceDict[audioSourceName];
}

return GetCurrentAudioSource(audioSourceName);
}

private AudioSource GetCurrentAudioSource()
{
foreach (var source in audioSourceDict)
{
if (!source.Value.isPlaying)
{
return source.Value;
}
}
return GetCurrentAudioSource(currentAudioName + count++);
}

private AudioSource GetCurrentAudioSource(string audioSourceName)
{
audioSourceDict.Add(audioSourceName, audioControl.AddComponent());
return audioSourceDict[audioSourceName];
}
}`


2.3.3 音效资源系统

`public class UploadAudioClipStrategy : IUploadAudioClip
{

// 音效路径
private readonly string audioPath;
// 播放的音效
private Dictionary<Enum, AudioClip> audioClipDict;

public UploadAudioClipStrategy()
{
audioPath = "Audio/";
audioClipDict = new Dictionary<Enum, AudioClip>();
}

public AudioClip GetAudioClip(Enum audioName)
{
if (audioClipDict.ContainsKey(audioName))
{
return audioClipDict[audioName];
}

AudioClip clip = Resources.Load(AudioClipPath(audioName));
audioClipDict.Add(audioName, clip);

return audioClipDict[audioName];
}

private string AudioClipPath(Enum audioName)
{
string audioType = audioName.GetType().Name;
return audioPath + audioType + "/" + audioName;
}
}
`

2.3.4 音效系统

`
public abstract class AudioManagerBase : IPlayAudio
{
public IUploadAudioSource UploadAudioSource { get; protected set; }
public IUploadAudioClip UploadAudioClip { get; protected set; }

protected AudioManagerBase() : this(new UploadAudioSourceStrategy(), new UploadAudioClipStrategy())
{

}

protected AudioManagerBase(IUploadAudioSource uploadAudioSource, IUploadAudioClip uploadAudioClip)
{
UploadAudioSource = uploadAudioSource;
UploadAudioClip = uploadAudioClip;
}

public void PlayAudio(Enum audioName, float volume, bool isLoop, string audioSourceName)
{
AudioClip clip = UploadAudioClip.GetAudioClip(audioName);
AudioSource audioSource = UploadAudioSource.GetAudioSource(audioSourceName);
audioSource.clip = clip;
audioSource.volume = volume;
audioSource.loop = isLoop;
audioSource.Play();
}

public void StopAudio(string audioSourceName)
{
AudioSource audioSource = UploadAudioSource.GetAudioSource(audioSourceName);
audioSource.loop = false;
audioSource.Stop();
}
}`


`
public class AudioSourceManager : AudioManagerBase {

public const string BgAudioName = "BgAudio";

region 播放音乐的调用方式

public void PlayAudio(AudioType.Dialogue audioName, float volume = 1.0f, bool isLoop = false, string audioSourceName = "")
{
base.PlayAudio(audioName, volume, isLoop, audioSourceName);
}

public void PlayAudio(AudioType.ScreenOnClick audioName, float volume = 1.0f, bool isLoop = false, string audioSourceName = "")
{
base.PlayAudio(audioName, volume, isLoop, audioSourceName);
}

public void PlayAudio(AudioType.SpecialEffects audioName, float volume = 1.0f, bool isLoop = false, string audioSourceName = "")
{
base.PlayAudio(audioName, volume, isLoop, audioSourceName);
}

public void PlayAudio(AudioType.Other audioName, float volume = 1.0f, bool isLoop = false, string audioSourceName = "")
{
base.PlayAudio(audioName, volume, isLoop, audioSourceName);
}

public void PlayAudio(AudioType.BackgroundMusic audioName, string audioSourceName = BgAudioName, float volume = 1.0f, bool isLoop = true)
{
PlayAudio(audioName, volume, isLoop, audioSourceName);
}

endregion

}
`


2.3.5 播放测试

`using UnityEngine;

public class TestC : MonoBehaviour {

private void Start()
{
AudioSourceManager audioSourceManager = new AudioSourceManager();
audioSourceManager.PlayAudio(AudioType.BackgroundMusic.BgMusic);
audioSourceManager.PlayAudio(AudioType.ScreenOnClick.Correct);
audioSourceManager.PlayAudio(AudioType.ScreenOnClick.Error);
}
}`

2.4 常用方法扩展

public interface IUploadAudioSource { 。。。 // 停止选择的部分音效 void StopGroupAudio(Func<string, bool> stopGroupAudio); }

public class UploadAudioSourceStrategy : IUploadAudioSource{ 。。。 public void StopGroupAudio(Func<string, bool> stopGroupAudio) { foreach (var source in audioSourceDict) { if (stopGroupAudio(source.Key)) { source.Value.loop = false; source.Value.Stop(); } } } }

`public abstract class AudioManagerBase : IPlayAudio{
。。。
public void Reset(Func<string, bool> stopGroupAudio)
{
UploadAudioSource.StopGroupAudio(stopGroupAudio);
}

public float PlayAudioTime(Enum audioName)
{
if (UploadAudioClip.GetAudioClip(audioName) == null)
{
Debug.Log("Error: " + "The music file could not be found");
return 0.0f;
}
return UploadAudioClip.GetAudioClip(audioName).length;
}
}`

`public class AudioSourceManager : AudioManagerBase, ISingleton
{
。。。
private AudioSourceManager() { }

public const string BgAudioName = "BgAudio"; }`

`public class TestC : MonoBehaviour {

private void Start()
{
SingletonManager.GetSingleton().PlayAudio(AudioType.BackgroundMusic.BgMusic);
SingletonManager.GetSingleton().PlayAudio(AudioType.ScreenOnClick.Correct);
SingletonManager.GetSingleton().PlayAudio(AudioType.ScreenOnClick.Error);

}
}`

posted @ 2019-02-01 17:11  CDCDDCDC  阅读(684)  评论(1)    收藏  举报