using UnityEngine; using System; using System.Collections.Generic; using Spine.Unity; public class BattlePreloadManager { private BattleCacheManager cacheManager = new BattleCacheManager(); private BattleUnloadManager unloadManager = new BattleUnloadManager(); private bool isLoading = false; public BattleCacheManager CacheManager => cacheManager; public BattleUnloadManager UnloadManager => unloadManager; /// /// 预加载战斗资源 /// public void PreloadBattleResources(string battleGuid, List redTeamList, List blueTeamList, Action progressCallback, Action completeCallback) { if (isLoading) { Debug.LogWarning("BattlePreloadManager: Already loading, ignoring request"); return; } isLoading = true; var redTeamInfo = AnalyzeTeamList(redTeamList, true); var blueTeamInfo = AnalyzeTeamList(blueTeamList, false); // ===== 合并红蓝队资源,统一注册 ===== var allSpineResources = new List(); var allAudioResources = new List(); allSpineResources.AddRange(redTeamInfo.SpineResources); allSpineResources.AddRange(blueTeamInfo.SpineResources); allAudioResources.AddRange(redTeamInfo.AudioResources); allAudioResources.AddRange(blueTeamInfo.AudioResources); cacheManager.RegisterBattlefieldResources(battleGuid, allSpineResources, allAudioResources); StartPreload(allSpineResources, allAudioResources, battleGuid, progressCallback, () => { isLoading = false; completeCallback?.Invoke(); }); } private TeamResTracker.TeamResourceInfo AnalyzeTeamList(List teamList, bool isPersistent) { var combinedInfo = new TeamResTracker.TeamResourceInfo(); if (teamList == null || teamList.Count == 0) { return combinedInfo; } foreach (var team in teamList) { if (team == null) continue; var teamInfo = TeamResTracker.AnalyzeTeam(team, isPersistent); MergeResourceInfo(combinedInfo, teamInfo); } return combinedInfo; } private void MergeResourceInfo(TeamResTracker.TeamResourceInfo target, TeamResTracker.TeamResourceInfo source) { // 合并Spine资源(去重) foreach (var res in source.SpineResources) { if (!ContainsResource(target.SpineResources, res)) { target.SpineResources.Add(res); } } // 合并音频资源(去重) foreach (var res in source.AudioResources) { if (!ContainsResource(target.AudioResources, res)) { target.AudioResources.Add(res); } } } private bool ContainsResource(List list, BattleResCache.ResourceIdentifier resource) { foreach (var item in list) { if (item.GetKey() == resource.GetKey()) { return true; } } return false; } private void StartPreload(List spineResources, List audioResources, string battleGuid, Action progressCallback, Action completeCallback) { int totalResources = spineResources.Count + audioResources.Count; if (totalResources == 0) { Debug.Log("BattlePreloadManager: No resources to preload"); completeCallback?.Invoke(); return; } Debug.Log($"BattlePreloadManager: Preloading {totalResources} resources for battlefield {battleGuid}"); Debug.Log($" Spine={spineResources.Count}, Audio={audioResources.Count}"); int loadedCount = 0; Action onSingleComplete = () => { loadedCount++; float progress = (float)loadedCount / totalResources; progressCallback?.Invoke(progress); if (loadedCount >= totalResources) { Debug.Log($"BattlePreloadManager: Completed! {cacheManager.GetCacheStats(battleGuid)}"); completeCallback?.Invoke(); } }; // 异步加载所有Spine资源 foreach (var identifier in spineResources) { LoadSpineAsync(identifier, battleGuid, onSingleComplete); } // 异步加载所有Audio资源 foreach (var identifier in audioResources) { LoadAudioAsync(identifier, battleGuid, onSingleComplete); } } private void LoadSpineAsync(BattleResCache.ResourceIdentifier identifier, string battleGuid, Action onComplete) { string key = identifier.GetKey(); ResManager.Instance.LoadAssetAsync( identifier.Directory, identifier.AssetName, (success, asset) => { if (success && asset != null) { var skeletonData = asset as SkeletonDataAsset; if (skeletonData != null) { var cachedRes = new BattleResCache.CachedResource(identifier, skeletonData, false); cacheManager.UpdateResourceReference(key, cachedRes, battleGuid, identifier.OwnerId); Debug.Log($"BattlePreloadManager: Loaded spine: {key}"); } } else { Debug.LogError($"BattlePreloadManager: Failed to load spine: {key}"); } onComplete?.Invoke(); } ); } private void LoadAudioAsync(BattleResCache.ResourceIdentifier identifier, string battleGuid, Action onComplete) { string key = identifier.GetKey(); ResManager.Instance.LoadAssetAsync( identifier.Directory, identifier.AssetName, (success, asset) => { if (success && asset != null) { var audioClip = asset as AudioClip; if (audioClip != null) { var cachedRes = new BattleResCache.CachedResource(identifier, audioClip, false); cacheManager.UpdateResourceReference(key, cachedRes, battleGuid, identifier.OwnerId); Debug.Log($"BattlePreloadManager: Loaded audio: {key}"); } } else { Debug.LogError($"BattlePreloadManager: Failed to load audio: {key}"); } onComplete?.Invoke(); }, false // needExt = false ); } }