You've already forked taptap2024_GJ_chidouren
253 lines
8.9 KiB
C#
253 lines
8.9 KiB
C#
using System.Collections.Generic;
|
||
using System.Threading.Tasks;
|
||
using Audio;
|
||
using Framework.Asset;
|
||
using UnityEngine;
|
||
using YooAsset;
|
||
using AudioType = Framework.Audio.AudioType;
|
||
|
||
namespace System.AudioHandler
|
||
{
|
||
/// <summary>
|
||
/// 单独分离的音频资源加载器,方便后续升级资源加载策略
|
||
/// </summary>
|
||
public class AudioSourceHandler : IAudioSourceHandler
|
||
{
|
||
private static readonly Dictionary<AudioType, string> _AUDIO_PATH = new Dictionary<AudioType, string>()
|
||
{
|
||
{AudioType.BGM, "BGM"},
|
||
{AudioType.BSE, "BSE"},
|
||
{AudioType.SOUND, "SE"}
|
||
};
|
||
|
||
private readonly string _rootPath;
|
||
|
||
private Dictionary<string, AudioAsset> _audioSource;
|
||
private Dictionary<string, int> _audioReferenceCount;
|
||
private List<string> _audioPaths;
|
||
|
||
//用于编辑器状态下监视资源状态
|
||
public Dictionary<string, string> editorLog;
|
||
public Dictionary<string, string> EditorLog() => this.editorLog;
|
||
|
||
private string AudioFullPath(AudioType audioType, string audioName)
|
||
{
|
||
audioName = audioName.Replace("\\", "/");
|
||
return $"{this._rootPath}/{_AUDIO_PATH[audioType]}/{audioName}";
|
||
}
|
||
|
||
public AudioSourceHandler(string rootPath)
|
||
{
|
||
this._rootPath = rootPath;
|
||
this._audioReferenceCount = new Dictionary<string, int>();
|
||
this._audioSource = new Dictionary<string, AudioAsset>();
|
||
this._audioPaths =
|
||
new List<string>(AssetManager.Instance.GetResourceLocation(this._rootPath));
|
||
#if UNITY_EDITOR
|
||
this.editorLog = new Dictionary<string, string>();
|
||
#endif
|
||
}
|
||
|
||
public bool IsAsync()
|
||
{
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 异步加载音频资源
|
||
/// </summary>
|
||
/// <param name="audioType"></param>
|
||
/// <param name="audioName"></param>
|
||
/// <returns></returns>
|
||
public async Task<AudioClip> GetAudioClipAsync(AudioType audioType, string audioName)
|
||
{
|
||
var audioKey = audioType + audioName;
|
||
//当指定音效没有或者其资源为null时,通过ab包加载
|
||
if (!this._audioSource.ContainsKey(audioKey) || this._audioSource[audioKey] == null)
|
||
{
|
||
var fullpath = AudioFullPath((AudioType) audioType, audioName);
|
||
var path = GetAudioPath(fullpath);
|
||
if (path == null)
|
||
{
|
||
return null;
|
||
}
|
||
if (!AssetManager.Instance.CheckLocationValid (path , false))
|
||
{
|
||
#if UNITY_EDITOR
|
||
Debug.Log ("【AudioManager】无效的音频资源路径:" + path);
|
||
#endif
|
||
return null;
|
||
}
|
||
var audioAsset = AssetManager.Instance.LoadAssetRequestAsync<AudioClip>(path , false);
|
||
await audioAsset.Task;
|
||
this._audioSource[audioKey] = new AudioAsset(audioAsset , audioKey);
|
||
this._audioReferenceCount[audioKey] = 0;
|
||
}
|
||
|
||
var audioClip = this._audioSource[audioKey].Clip;
|
||
this._audioReferenceCount[audioKey] += audioClip != null ? 1 : 0;
|
||
#if UNITY_EDITOR
|
||
RefreshLog();
|
||
#endif
|
||
return audioClip;
|
||
}
|
||
|
||
|
||
public string GetAudioPath(string pullPath)
|
||
{
|
||
pullPath += ".";
|
||
foreach (var audioPath in this._audioPaths)
|
||
{
|
||
if (audioPath.IndexOf(pullPath, StringComparison.Ordinal) == 0)
|
||
{
|
||
return audioPath;
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取一个音频资源
|
||
/// </summary>
|
||
/// <param name="audioType"></param>
|
||
/// <param name="audioName"></param>
|
||
/// <returns></returns>
|
||
public AudioClip GetAudioClip(AudioType audioType, string audioName)
|
||
{
|
||
var audioKey = audioType + audioName;
|
||
//当指定音效没有或者其资源为null时,通过ab包加载
|
||
if (!this._audioSource.ContainsKey(audioKey) || this._audioSource[audioKey] == null)
|
||
{
|
||
var fullpath = AudioFullPath((AudioType) audioType, audioName);
|
||
var path = GetAudioPath(fullpath);
|
||
if (path == null)
|
||
{
|
||
return null;
|
||
}
|
||
if (!AssetManager.Instance.CheckLocationValid (path , false))
|
||
{
|
||
// #if UNITY_EDITOR
|
||
// Debug.Log ("【AudioManager】无效的音频资源路径:" + path);
|
||
// #endif
|
||
Debug.Log ("【AudioManager】无效的音频资源路径:" + path);
|
||
return null;
|
||
}
|
||
var audioAsset = AssetManager.Instance.LoadAssetRequest<AudioClip>(path , false);
|
||
this._audioSource[audioKey] = new AudioAsset(audioAsset , audioKey);
|
||
this._audioReferenceCount[audioKey] = 0;
|
||
}
|
||
|
||
var audioClip = this._audioSource[audioKey].Clip;
|
||
this._audioReferenceCount[audioKey] += audioClip != null ? 1 : 0;
|
||
#if UNITY_EDITOR
|
||
RefreshLog();
|
||
#endif
|
||
return audioClip;
|
||
}
|
||
|
||
public void OnAudioInvalid(AudioType audioType, string audioName)
|
||
{
|
||
var audioKey = audioType + audioName;
|
||
if (this._audioReferenceCount.ContainsKey(audioKey) && this._audioReferenceCount[audioKey] >= 1)
|
||
{
|
||
this._audioReferenceCount[audioKey] -= 1;
|
||
if (this._audioReferenceCount[audioKey] == 0)
|
||
{
|
||
if (audioType == AudioType.BGM || audioType == AudioType.BSE)
|
||
{
|
||
var audioAsset = this._audioSource[audioKey];
|
||
this._audioSource[audioKey] = null;
|
||
audioAsset.KillAsset();
|
||
}
|
||
#if UNITY_EDITOR
|
||
RefreshLog();
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 卸载所有未使用的音效资源
|
||
/// </summary>
|
||
public void UnLoadAllInvalid()
|
||
{
|
||
List<string> sourceKeys = new List<string>(this._audioSource.Keys);
|
||
for (int i = sourceKeys.Count - 1; i >= 0; i--)
|
||
{
|
||
var audioSourceKey = sourceKeys[i];
|
||
if (this._audioReferenceCount[audioSourceKey] == 0)
|
||
{
|
||
// ushort group = ushort.Parse(audioSourceKey.Substring(0, 1));
|
||
// string audioName = audioSourceKey.Substring(1);
|
||
var audioAsset = this._audioSource[audioSourceKey];
|
||
audioAsset.KillAsset();
|
||
this._audioSource.Remove(audioSourceKey);
|
||
this._audioReferenceCount.Remove(audioSourceKey);
|
||
#if UNITY_EDITOR
|
||
this.editorLog.Remove(audioSourceKey);
|
||
#endif
|
||
}
|
||
}
|
||
#if UNITY_EDITOR
|
||
RefreshLog();
|
||
#endif
|
||
}
|
||
|
||
|
||
public void RefreshLog()
|
||
{
|
||
#if UNITY_EDITOR
|
||
foreach (var audioSourceKey in this._audioSource.Keys)
|
||
{
|
||
this.editorLog[audioSourceKey] =
|
||
$"\t{this._audioSource[audioSourceKey] != null} \t{this._audioReferenceCount[audioSourceKey]}";
|
||
}
|
||
#endif
|
||
}
|
||
|
||
public float[] LoadVolume()
|
||
{
|
||
var volumes = new float[3] {1, 1, 1};
|
||
volumes[0] = Account.Instance.AccountSystemData.BGMValue;
|
||
volumes[1] = Account.Instance.AccountSystemData.BSEValue;
|
||
volumes[2] = Account.Instance.AccountSystemData.SEValue;
|
||
return volumes;
|
||
}
|
||
|
||
public void SaveVolume(float bgm, float bse, float se)
|
||
{
|
||
Account.Instance.AccountSystemData.BGMValue = bgm;
|
||
Account.Instance.AccountSystemData.BSEValue = bse;
|
||
Account.Instance.AccountSystemData.SEValue = se;
|
||
Account.Instance.Save(Framework.Save.SaveData.System);
|
||
}
|
||
}
|
||
|
||
public class AudioAsset
|
||
{
|
||
private AudioClip _clip;
|
||
private AssetHandle _assetRequest;
|
||
private string _key;
|
||
|
||
public AudioAsset(AssetHandle assetRequest, string key)
|
||
{
|
||
this._assetRequest = assetRequest;
|
||
this._key = key;
|
||
if (assetRequest == null || assetRequest.AssetObject == null)
|
||
{
|
||
Debug.Log("Error Audio Path : " + key + " path: " + assetRequest?.GetAssetInfo ().AssetPath);
|
||
return;
|
||
}
|
||
this._clip = assetRequest.AssetObject as AudioClip;
|
||
}
|
||
|
||
public void KillAsset()
|
||
{
|
||
this._clip = null;
|
||
this._assetRequest.Release();
|
||
}
|
||
|
||
public string Key => this._key;
|
||
public AudioClip Clip => this._clip;
|
||
}
|
||
} |