From 1df0666c918a3510397524417760878ad0236fa3 Mon Sep 17 00:00:00 2001 From: Oliver Wong Date: Thu, 14 May 2026 11:35:38 +0800 Subject: [PATCH] feat: Unified ResourceLoader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 统一 `ResourceLoader`类,负责同步/异步加载资源,并对已加载的资源缓存。 - 修改 `MusicTransition`, `AudioSystem`, `LongAudioContainerPlayer`, `MusicSegment`, 'SfxSystem`, `HapticSystem`使用最新的`ResourceLoader`。 --- .../OCES/Audio/HandWritten/AudioSystem.cs | 13 ++- .../LongAudio/LongAudioContainerPlayer.cs | 7 +- .../HandWritten/LongAudio/MusicSegment.cs | 2 +- .../OCES/Audio/HandWritten/SfxSystem.cs | 7 +- .../OCES/Haptic/Handwritten/HapticSystem.cs | 11 ++- Assets/Scripts/OCES/ResourceLoader.cs | 80 +++++++++++++++++++ Assets/Scripts/OCES/ResourceLoader.cs.meta | 3 + 7 files changed, 116 insertions(+), 7 deletions(-) create mode 100644 Assets/Scripts/OCES/ResourceLoader.cs create mode 100644 Assets/Scripts/OCES/ResourceLoader.cs.meta diff --git a/Assets/Scripts/OCES/Audio/HandWritten/AudioSystem.cs b/Assets/Scripts/OCES/Audio/HandWritten/AudioSystem.cs index 940966b..06bd585 100644 --- a/Assets/Scripts/OCES/Audio/HandWritten/AudioSystem.cs +++ b/Assets/Scripts/OCES/Audio/HandWritten/AudioSystem.cs @@ -18,6 +18,8 @@ namespace OCES.Audio public IReadOnlyDictionary ActiveStates { get; private set; } public enum ConsoleLogLevel { Off, Log, Warning, Error } //TODO 实现这个功能 + internal ResourceLoader ResourceLoader; + const string k_audioConfigPath = "AudioData"; const string k_audioResourcePath = "Audios"; @@ -29,6 +31,7 @@ namespace OCES.Audio AudioMixer m_mixer; Tween m_lowpassTween; + // ───────────────────────────────────────────── // 公开接口 // ───────────────────────────────────────────── @@ -279,8 +282,10 @@ namespace OCES.Audio } Instance = this; DontDestroyOnLoad(gameObject); + + this.ResourceLoader = gameObject.AddComponent(); - this.m_mixer = Resources.Load("Audios/Master"); + this.m_mixer = this.ResourceLoader.LoadSync("Audios/Master"); // ── SFX 调度器 ── // AudioSystem.cs 中 @@ -409,9 +414,13 @@ namespace OCES.Audio public static T Load(string tableName) where T : IBinarySerializable, new() { - TextAsset bytes = Resources.Load(tableName); + TextAsset bytes = AudioSystem.Instance.ResourceLoader.LoadSync(tableName); if (!bytes) + { Debug.LogError($"未找到表 {tableName}"); + return default; + } + IBinarySerializable data = new T(); bool readOk = FileManager.ReadBinaryDataFromBytes(bytes.bytes, ref data); if (readOk) diff --git a/Assets/Scripts/OCES/Audio/HandWritten/LongAudio/LongAudioContainerPlayer.cs b/Assets/Scripts/OCES/Audio/HandWritten/LongAudio/LongAudioContainerPlayer.cs index 2c9c48e..6285ec0 100644 --- a/Assets/Scripts/OCES/Audio/HandWritten/LongAudio/LongAudioContainerPlayer.cs +++ b/Assets/Scripts/OCES/Audio/HandWritten/LongAudio/LongAudioContainerPlayer.cs @@ -340,7 +340,12 @@ namespace OCES.Audio return null; } - AudioClip clip = Resources.Load($"Audios/{segment.Name}"); + // AudioClip clip = Resources.Load($"Audios/{segment.Name}"); + AudioClip clip = null; + AudioSystem.Instance.ResourceLoader.LoadAsync($"Audios/{segment.Name}", loadedClip => + { + clip = loadedClip; + }); if (!clip) { Debug.LogError($"[LongAudioContainerPlayer] 音频文件未找到: {segment.Name}"); diff --git a/Assets/Scripts/OCES/Audio/HandWritten/LongAudio/MusicSegment.cs b/Assets/Scripts/OCES/Audio/HandWritten/LongAudio/MusicSegment.cs index e61ac0d..f86c810 100644 --- a/Assets/Scripts/OCES/Audio/HandWritten/LongAudio/MusicSegment.cs +++ b/Assets/Scripts/OCES/Audio/HandWritten/LongAudio/MusicSegment.cs @@ -16,7 +16,7 @@ namespace OCES.Audio { foreach (MusicSegment segment in this.m_musicSegmentInfos.Values) { - AudioClip clip = Resources.Load($"Audios/{segment.Name}"); + AudioClip clip = AudioSystem.Instance.ResourceLoader.LoadSync($"Audios/{segment.Name}"); if (!clip) { Debug.LogError($"[MusicSegmentConfig] 音频文件未找到: {segment.Name}, SegmentId: {segment.Id}"); diff --git a/Assets/Scripts/OCES/Audio/HandWritten/SfxSystem.cs b/Assets/Scripts/OCES/Audio/HandWritten/SfxSystem.cs index 11c73bf..24556d7 100644 --- a/Assets/Scripts/OCES/Audio/HandWritten/SfxSystem.cs +++ b/Assets/Scripts/OCES/Audio/HandWritten/SfxSystem.cs @@ -405,7 +405,12 @@ namespace OCES.Audio bool SetupSource(AudioSource source, ActiveSound activeSound, int clipIndex = 0) { AudioObject audioObject = activeSound.AudioObject; - AudioClip clip = Resources.Load($"Audios/{audioObject.Name[clipIndex]}"); // TODO 抽象同一资源加载接口 + //AudioClip clip = Resources.Load($"Audios/{audioObject.Name[clipIndex]}"); // TODO 抽象同一资源加载接口 + AudioClip clip = null; + AudioSystem.Instance.ResourceLoader.LoadAsync($"Audios/{audioObject.Name[clipIndex]}", loadedClip => + { + clip = loadedClip; + }); if (!clip) { Debug.LogError($"音频文件未找到:{audioObject.Name[clipIndex]}"); diff --git a/Assets/Scripts/OCES/Haptic/Handwritten/HapticSystem.cs b/Assets/Scripts/OCES/Haptic/Handwritten/HapticSystem.cs index 47b7120..0b9f9ad 100644 --- a/Assets/Scripts/OCES/Haptic/Handwritten/HapticSystem.cs +++ b/Assets/Scripts/OCES/Haptic/Handwritten/HapticSystem.cs @@ -13,6 +13,8 @@ namespace OCES.Haptic public bool IsHapticSupported; [NonSerialized] public bool IsMeetsAdvanceRequirements; + + internal ResourceLoader ResourceLoader; HapticObjectConfig m_hapticObjects; const string k_hapticConfigPath = "HapticData/"; @@ -110,6 +112,8 @@ namespace OCES.Haptic } Instance = this; DontDestroyOnLoad(gameObject); + + this.ResourceLoader = gameObject.AddComponent(); this.m_hapticObjects = HapticConfigLoader.Load(k_hapticConfigPath + "HapticObject"); this.IsHapticSupported = DeviceCapabilities.isVersionSupported; @@ -118,16 +122,19 @@ namespace OCES.Haptic static HapticClip GetHapticClip(HapticObject hapticObject) { - return Resources.Load(k_hapticResourcesPath + hapticObject.Payload); + return Instance.ResourceLoader.LoadSync(k_hapticResourcesPath + hapticObject.Payload); } static class HapticConfigLoader { internal static T Load(string tableName) where T : IBinarySerializable, new() { - TextAsset bytes = Resources.Load(tableName); + TextAsset bytes = Instance.ResourceLoader.LoadSync(tableName); if (!bytes) + { Debug.LogError($"未找到表 {tableName}"); + return default; + } IBinarySerializable data = new T(); bool readOk = FileManager.ReadBinaryDataFromBytes(bytes.bytes, ref data); if (readOk) diff --git a/Assets/Scripts/OCES/ResourceLoader.cs b/Assets/Scripts/OCES/ResourceLoader.cs new file mode 100644 index 0000000..fbaac74 --- /dev/null +++ b/Assets/Scripts/OCES/ResourceLoader.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using JetBrains.Annotations; +using UnityEngine; +using Object = UnityEngine.Object; + +namespace OCES +{ + public class ResourceLoader : MonoBehaviour + { + readonly Dictionary m_cachedObjects = new(); + readonly Dictionary>> m_pendingCallbacks = new(); + + [CanBeNull] + internal T LoadSync(string path) where T : Object + { + if (this.m_cachedObjects.TryGetValue(path, out Object cachedObject)) + { + return cachedObject as T; + } + + T newObject = Resources.Load(path); + this.m_cachedObjects.Add(path, newObject); + return newObject; + } + + internal void LoadAsync(string path, Action onComplete) where T : Object + { + if (this.m_cachedObjects.TryGetValue(path, out Object cachedObject)) + { + onComplete?.Invoke(cachedObject as T); + return; + } + + if (this.m_pendingCallbacks.TryGetValue(path, out List> callbacks)) + { + callbacks.Add(obj => onComplete?.Invoke(obj as T)); + return; + } + + this.m_pendingCallbacks[path] = new List> { obj => onComplete?.Invoke(obj as T) }; + ResourceRequest newRequest = Resources.LoadAsync(path); + StartCoroutine(HandleAsyncLoadCompletion(path, newRequest)); + } + + IEnumerator HandleAsyncLoadCompletion(string path, ResourceRequest request) + { + yield return request; + + if (request.asset) + { + this.m_cachedObjects[path] = request.asset; + } + + if (this.m_pendingCallbacks.Remove(path, out List> callbacks)) + { + foreach (Action callback in callbacks) + { + callback?.Invoke(request.asset); + } + } + } + + internal void PreloadAsync(string[] paths) + { + + } + + internal void Release(string path) + { + + } + + internal void ReleaseUnused() + { + + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/OCES/ResourceLoader.cs.meta b/Assets/Scripts/OCES/ResourceLoader.cs.meta new file mode 100644 index 0000000..44aa882 --- /dev/null +++ b/Assets/Scripts/OCES/ResourceLoader.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 845d98765be843f9a943f41f45cdf013 +timeCreated: 1778573329 \ No newline at end of file