补充博客把音效的课件加进来
namespace YouYou
{
/// <summary>
/// 音频组件
/// </summary>
public class AudioComponent : YouYouBaseComponent, IUpdateComponent
{
private AudioManager m_AudioManager;
[Header("释放间隔")]
[SerializeField]
private int m_ReleaseInterval = 120;
protected override void OnAwake()
{
base.OnAwake();
m_AudioManager = new AudioManager(m_ReleaseInterval);
GameEntry.RegisterUpdateComponent(this);
}
public void OnUpdate()
{
m_AudioManager.OnUpdate();
}
public override void Shutdown()
{
GameEntry.RemoveUpdateComponent(this);
ShopAllAudio();
StopBGM();
}
/// <summary>
/// 加载音频文件
/// </summary>
/// <param name="onComplete"></param>
public void LoadBanks(BaseAction onComplete)
{
m_AudioManager.LoadBanks(onComplete);
}
#region BGM
/// <summary>
/// 播放BGM
/// </summary>
public void PlayBGM(int audioId)
{
Sys_AudioEntity entity = GameEntry.DataTable.DataTableManager.Sys_AudioDBModel.GetDic(audioId);
if (entity != null)
{
PlayBGM(entity.AssetPath, entity.Volume);
}
else
{
GameEntry.LogError("BGM不存在ID={0}", audioId);
}
}
/// <summary>
/// 播放BGM
/// </summary>
public void PlayBGM(string assetPath, float volume = 1)
{
m_AudioManager.PlayBGM(assetPath, volume);
}
/// <summary>
/// 设置BGM音量
/// </summary>
/// <param name="value"></param>
public void SetBGMVolume(float value)
{
m_AudioManager.SetBGMVolume(value);
}
/// <summary>
/// 暂停BGM
/// </summary>
/// <param name="pause"></param>
public void PauseBGM(bool pause)
{
m_AudioManager.PauseBGM(pause);
}
/// <summary>
/// 停止播放BGM
/// </summary>
public void StopBGM()
{
m_AudioManager.StopBGM();
}
/// <summary>
/// 开始播放BGM
/// </summary>
public void StartBGM()
{
m_AudioManager.StartBGM();
}
#endregion
#region 音效
/// <summary>
/// 播放音效
/// </summary>
public int PlayAydio(int audioId, string parameterName = null, float value = 0, Vector3 pos3D = default)
{
Sys_AudioEntity entity = GameEntry.DataTable.DataTableManager.Sys_AudioDBModel.GetDic(audioId);
if (entity != null)
{
return PlayAydio(entity.AssetPath, entity.Volume, parameterName, value, entity.Is3D == 1, pos3D);
}
else
{
GameEntry.LogError("Audio不存在Id = {0}", audioId);
return -1;
}
}
/// <summary>
/// 播放音效
/// </summary>
public int PlayAydio(string assetPath, float volume, string parameterName, float value, bool is3D, Vector3 pos3D)
{
return m_AudioManager.PlayAudio(assetPath, volume, parameterName, value, is3D, pos3D);
}
/// <summary>
/// 设置音效参数
/// </summary>
public void SetParameterForAudio(int serialId, string parameterName, float value)
{
m_AudioManager.SetParameterForAudio(serialId, parameterName, value);
}
/// <summary>
/// 暂停某个音效
/// </summary>
/// <param name="serialId"></param>
/// <param name="paused"></param>
/// <returns></returns>
public bool PausedAudio(int serialId, bool paused = true)
{
return m_AudioManager.PausedAudio(serialId, paused);
}
/// <summary>
/// 停止某个音效
/// </summary>
/// <param name="serialId"></param>
/// <param name="mode"></param>
/// <returns></returns>
internal bool StopAudio(int serialId, FMOD.Studio.STOP_MODE mode = FMOD.Studio.STOP_MODE.IMMEDIATE)
{
return m_AudioManager.StopAudio(serialId, mode);
}
/// <summary>
/// 停止所有音效
/// </summary>
public void ShopAllAudio()
{
m_AudioManager.ShopAllAudio();
}
#endregion
}
}
namespace YouYou
{
/// <summary>
/// 音频管理器
/// </summary>
public class AudioManager : ManagerBase
{
internal AudioManager(int releaseInterval)
{
m_ReleaseInterval = releaseInterval;
}
internal void OnUpdate()
{
//多长时间释放一次,是在Updata中
if (Time.time > m_NextReleaseTime + m_ReleaseInterval)
{
m_NextReleaseTime = Time.time;
Release();
}
}
internal void LoadBanks(BaseAction onComplete)
{
#if DISABLE_ASSETBUNDLE
string[] arr = Directory.GetFiles(Application.dataPath + "/Download/Audio/", "*.bytes");
for (int i = 0; i < arr.Length; i++)
{
FileInfo file = new FileInfo(arr[i]);
TextAsset asset = UnityEditor.AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/Download/Audio/" + file.Name);
RuntimeManager.LoadBank(asset);
}
if (onComplete != null) onComplete();
#elif ASSETBUNDLE
GameEntry.Resource.ResourceLoaderManager.LoadAssetBundle(ConstDefine.AudioAssetBundlePath, onComplete: (AssetBundle bundle) =>
{
TextAsset[] arr = bundle.LoadAllAssets<TextAsset>();
int len = arr.Length;
for (int i = 0; i < len; i++)
{
RuntimeManager.LoadBank(arr[i]);
}
if (onComplete != null) onComplete();
});
#elif RESOURCES
TextAsset[] assets = Resources.LoadAll<TextAsset>("Audio");
for (int i = 0; i < assets.Length; i++)
{
RuntimeManager.LoadBank(assets[i]);
}
if (onComplete != null) onComplete();
#endif
}
#region BGM
private string m_CurrBGMAudio;
private float m_CurrBGMVolume;
private float m_CurrBGMMaxVolume;
private EventInstance BGMEvent;
private TimeAction m_CurrBGMTimeAction;
/// <summary>
/// 播放BGM
/// </summary>
/// <param name="bgmPath"></param>
internal void PlayBGM(string bgmPath, float volume = 1)
{
m_CurrBGMAudio = bgmPath;
m_CurrBGMMaxVolume = volume;
CheckBGMEventInstance();
}
/// <summary>
/// BGM切换参数
/// </summary>
private void CheckBGMEventInstance(string switchName, float value)
{
BGMEvent.setParameterByName(switchName, value);
}
/// <summary>
/// 设置BGM音量
/// </summary>
/// <param name="value"></param>
internal void SetBGMVolume(float value)
{
BGMEvent.setVolume(value);
}
/// <summary>
/// 暂停BGM
/// </summary>
/// <param name="pause"></param>
internal void PauseBGM(bool pause)
{
if (!BGMEvent.isValid()) CheckBGMEventInstance();
if (BGMEvent.isValid()) BGMEvent.setPaused(pause);
}
/// <summary>
/// 检查BGM实例把之前的释放掉
/// </summary>
private void CheckBGMEventInstance()
{
if (!string.IsNullOrEmpty(m_CurrBGMAudio))
{
if (BGMEvent.isValid())
{
BGMEvent.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
BGMEvent.release();
}
BGMEvent = RuntimeManager.CreateInstance(m_CurrBGMAudio);
m_CurrBGMVolume = 0;
SetBGMVolume(m_CurrBGMVolume);
BGMEvent.start();
//把音量逐渐变成Max
m_CurrBGMTimeAction = GameEntry.Time.CreateTimeAction();
m_CurrBGMTimeAction.Init(0, 0.05f, 100, null, (int loop) =>
{
m_CurrBGMVolume += 0.1f;
m_CurrBGMVolume = Mathf.Min(m_CurrBGMVolume, m_CurrBGMMaxVolume);
SetBGMVolume(m_CurrBGMVolume);
if (m_CurrBGMVolume == m_CurrBGMMaxVolume)
{
m_CurrBGMTimeAction.Stop();
}
}, null).Run();
}
}
/// <summary>
/// 停止播放BGM
/// </summary>
internal void StopBGM()
{
if (BGMEvent.isValid())
{
//把音量逐渐变成0 再停止
m_CurrBGMTimeAction = GameEntry.Time.CreateTimeAction();
m_CurrBGMTimeAction.Init(0, 0.05f, 100, null, (int loop) =>
{
m_CurrBGMVolume -= 0.1f;
m_CurrBGMVolume = Mathf.Max(m_CurrBGMVolume, 0);
SetBGMVolume(m_CurrBGMVolume);
if (m_CurrBGMVolume == 0)
{
m_CurrBGMTimeAction.Stop();
BGMEvent.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
}
}, () =>
{
BGMEvent.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
}).Run();
}
}
/// <summary>
/// 开始播放BGM
/// </summary>
internal void StartBGM()
{
BGMEvent.start();
}
#endregion
#region 音效
/// <summary>
/// 释放间隔
/// </summary>
private int m_ReleaseInterval = 120;
/// <summary>
/// 下次释放时间
/// </summary>
private float m_NextReleaseTime = 0f;
/// <summary>
/// 序号
/// </summary>
private int m_Serial = 0;
/// <summary>
/// 音效字典
/// </summary>
private Dictionary<int, EventInstance> m_CurrAudioEventsDic = new Dictionary<int, EventInstance>();
/// <summary>
/// 需要释放的音效编号
/// </summary>
private LinkedList<int> m_NeedRemoveList = new LinkedList<int>();
/// <summary>
/// 播放音效
/// </summary>
internal int PlayAudio(string eventPath, float volume = 1, string parameterName = null, float value = 0, bool is3D = false, Vector3 pos3D = default)
{
if (string.IsNullOrEmpty(eventPath)) return -1;
//生成一个音频
EventInstance eventInstance = RuntimeManager.CreateInstance(eventPath);
//设置音量
eventInstance.setVolume(volume);
//设置参数
if (!string.IsNullOrEmpty(parameterName)) eventInstance.setParameterByName(parameterName, value);
//设置3D音效,设置3D音效位置
if (is3D) eventInstance.set3DAttributes(pos3D.To3DAttributes());
eventInstance.start();
int serialId = m_Serial++;
m_CurrAudioEventsDic[serialId] = eventInstance;
return serialId;
}
/// <summary>
/// 设置音效参数
/// </summary>
internal void SetParameterForAudio(int serialId, string parameterName, float value)
{
EventInstance eventInstance;
if (m_CurrAudioEventsDic.TryGetValue(serialId, out eventInstance))
{
if (eventInstance.isValid()) eventInstance.setParameterByName(parameterName, value);
}
}
/// <summary>
/// 暂停某个音效
/// </summary>
/// <param name="serialId"></param>
/// <param name="paused"></param>
/// <returns></returns>
internal bool PausedAudio(int serialId, bool paused = true)
{
EventInstance eventInstance;
if (m_CurrAudioEventsDic.TryGetValue(serialId, out eventInstance))
{
if (eventInstance.isValid())
{
return eventInstance.setPaused(paused) == FMOD.RESULT.OK;
}
}
return false;
}
/// <summary>
/// 停止某个音效
/// </summary>
/// <param name="serialId"></param>
/// <param name="mode"></param>
/// <returns></returns>
internal bool StopAudio(int serialId, FMOD.Studio.STOP_MODE mode = FMOD.Studio.STOP_MODE.IMMEDIATE)
{
EventInstance eventInstance;
if (m_CurrAudioEventsDic.TryGetValue(serialId, out eventInstance))
{
if (eventInstance.isValid())
{
var result = eventInstance.stop(mode);
//释放掉
eventInstance.release();
//从字典中移除掉
m_CurrAudioEventsDic.Remove(serialId);
return result == FMOD.RESULT.OK;
}
}
return false;
}
/// <summary>
/// 停止所有音效
/// </summary>
internal void ShopAllAudio()
{
var enumerator = m_CurrAudioEventsDic.GetEnumerator();
while (enumerator.MoveNext())
{
EventInstance eventInstance = enumerator.Current.Value;
if (eventInstance.isValid())
{
var reselt = eventInstance.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
eventInstance.release();
}
}
m_CurrAudioEventsDic.Clear();
}
/// <summary>
/// 释放可释放的音效
/// </summary>
private void Release()
{
var lst = m_CurrAudioEventsDic.GetEnumerator();
while (lst.MoveNext())
{
EventInstance eventInstance = lst.Current.Value;
if (!eventInstance.isValid()) continue;
PLAYBACK_STATE state;
eventInstance.getPlaybackState(out state);
//音效的状态停止
if (state == PLAYBACK_STATE.STOPPED)
{
m_NeedRemoveList.AddLast(lst.Current.Key);
eventInstance.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
eventInstance.release();
}
}
LinkedListNode<int> currNode = m_NeedRemoveList.First;
while (currNode != null)
{
LinkedListNode<int> next = currNode.Next;
int serialId = currNode.Value;
m_CurrAudioEventsDic.Remove(serialId);
m_NeedRemoveList.Remove(currNode);
currNode = next;
}
}
#endregion
}
}
打开调用
关闭调用
通过速度控制声音的变幻,模拟汽车声音,混合音效
整个音频文件打一个资源包,初始资源,声音不需要加密
打包打好之后放入CDN的download文件夹下
预加载中