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;
|
|||
|
|
}
|
|||
|
|
}
|