From b1b9a387a63e1ce77cf387b90ec170c7a05bb53b Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期三, 03 十二月 2025 18:29:38 +0800
Subject: [PATCH] 125 战斗 替换加载蓝队逻辑 统一替换引用计数

---
 Main/System/Battle/BattleResources/BattleCacheManager.cs |  590 +++++++++++++++++++---------------------------------------
 1 files changed, 195 insertions(+), 395 deletions(-)

diff --git a/Main/System/Battle/BattleResources/BattleCacheManager.cs b/Main/System/Battle/BattleResources/BattleCacheManager.cs
index 86f9d04..e0c36b4 100644
--- a/Main/System/Battle/BattleResources/BattleCacheManager.cs
+++ b/Main/System/Battle/BattleResources/BattleCacheManager.cs
@@ -5,423 +5,115 @@
 public class BattleCacheManager
 {
     /// <summary>
-    /// 璧勬簮寮曠敤淇℃伅
+    /// 璧勬簮寮曠敤淇℃伅锛堟垬鍦� + 瑙掕壊缁村害锛�
     /// </summary>
     private class ResourceReference
     {
         public BattleResCache.CachedResource CachedResource;
-        public HashSet<string> OwnerIds = new HashSet<string>(); // 浣跨敤璇ヨ祫婧愮殑瑙掕壊ID闆嗗悎
+        // 璁板綍鍝簺鎴樺満鐨勫摢浜涜鑹插湪浣跨敤杩欎釜璧勬簮
+        // Key: battleGuid, Value: ownerIds
+        public Dictionary<string, HashSet<string>> BattlefieldOwners = new Dictionary<string, HashSet<string>>();
         
-        public int RefCount => OwnerIds.Count;
-        
-        public void AddOwner(string ownerId)
+        public int RefCount
         {
-            OwnerIds.Add(ownerId);
+            get
+            {
+                int count = 0;
+                foreach (var owners in BattlefieldOwners.Values)
+                {
+                    count += owners.Count;
+                }
+                return count;
+            }
         }
         
-        public void RemoveOwner(string ownerId)
+        /// <summary>
+        /// 娣诲姞鎴樺満+瑙掕壊鐨勫紩鐢�
+        /// </summary>
+        public void AddBattlefieldOwner(string battleGuid, string ownerId)
         {
-            OwnerIds.Remove(ownerId);
+            if (!BattlefieldOwners.ContainsKey(battleGuid))
+            {
+                BattlefieldOwners[battleGuid] = new HashSet<string>();
+            }
+            BattlefieldOwners[battleGuid].Add(ownerId);
+        }
+        
+        /// <summary>
+        /// 绉婚櫎鏁翠釜鎴樺満鐨勬墍鏈夊紩鐢�
+        /// </summary>
+        public void RemoveBattlefield(string battleGuid)
+        {
+            BattlefieldOwners.Remove(battleGuid);
         }
     }
     
-    // ===== 绾㈤槦璧勬簮锛氬叏灞�鍏变韩锛屾寜寮曠敤璁℃暟绠$悊 =====
-    private static Dictionary<string, ResourceReference> globalRedTeamSpineCache = 
+    // ===== 鍏ㄥ眬缁熶竴璧勬簮姹狅紙涓嶅啀鍖哄垎绾㈣摑闃燂級=====
+    private static Dictionary<string, ResourceReference> globalSpineCache = 
         new Dictionary<string, ResourceReference>();
     
-    private static Dictionary<string, ResourceReference> globalRedTeamAudioCache = 
+    private static Dictionary<string, ResourceReference> globalAudioCache = 
         new Dictionary<string, ResourceReference>();
     
-    // ===== 钃濋槦璧勬簮锛氭寜鎴樺満GUID闅旂 =====
-    private static Dictionary<string, Dictionary<string, BattleResCache.CachedResource>> blueTeamSpineCacheDict = 
-        new Dictionary<string, Dictionary<string, BattleResCache.CachedResource>>();
-    
-    private static Dictionary<string, Dictionary<string, BattleResCache.CachedResource>> blueTeamAudioCacheDict = 
-        new Dictionary<string, Dictionary<string, BattleResCache.CachedResource>>();
-    
-    // 闇�瑕佹坊鍔犵殑瀛楁
-    private static Dictionary<string, HashSet<string>> battlefieldRedTeamOwners = 
-        new Dictionary<string, HashSet<string>>();  // <battleGuid, ownerIds>
-    
     /// <summary>
-    /// 鑾峰彇Spine缂撳瓨锛堢孩闃熷叏灞�锛岃摑闃熸寜鎴樺満闅旂锛�
+    /// 娉ㄥ唽鎴樺満璧勬簮闇�姹傦紙绾㈤槦+钃濋槦涓�璧锋敞鍐岋級
     /// </summary>
-    public Dictionary<string, BattleResCache.CachedResource> GetSpineCache(bool isPersistent, string battleGuid = "")
+    public void RegisterBattlefieldResources(string battleGuid, 
+        List<BattleResCache.ResourceIdentifier> spineResources, 
+        List<BattleResCache.ResourceIdentifier> audioResources)
     {
-        if (isPersistent)
-        {
-            // 绾㈤槦锛氬皢寮曠敤瀛楀吀杞崲涓烘櫘閫氱紦瀛樺瓧鍏革紙鍏煎鍔犺浇鍣級
-            var cache = new Dictionary<string, BattleResCache.CachedResource>();
-            foreach (var kvp in globalRedTeamSpineCache)
-            {
-                cache[kvp.Key] = kvp.Value.CachedResource;
-            }
-            return cache;
-        }
-        else
-        {
-            // 钃濋槦锛氳繑鍥炴垬鍦轰笓灞炵紦瀛�
-            if (!blueTeamSpineCacheDict.ContainsKey(battleGuid))
-            {
-                blueTeamSpineCacheDict[battleGuid] = new Dictionary<string, BattleResCache.CachedResource>();
-            }
-            return blueTeamSpineCacheDict[battleGuid];
-        }
-    }
-    
-    /// <summary>
-    /// 鑾峰彇闊抽缂撳瓨锛堢孩闃熷叏灞�锛岃摑闃熸寜鎴樺満闅旂锛�
-    /// </summary>
-    public Dictionary<string, BattleResCache.CachedResource> GetAudioCache(bool isPersistent, string battleGuid = "")
-    {
-        if (isPersistent)
-        {
-            // 绾㈤槦锛氬皢寮曠敤瀛楀吀杞崲涓烘櫘閫氱紦瀛樺瓧鍏�
-            var cache = new Dictionary<string, BattleResCache.CachedResource>();
-            foreach (var kvp in globalRedTeamAudioCache)
-            {
-                cache[kvp.Key] = kvp.Value.CachedResource;
-            }
-            return cache;
-        }
-        else
-        {
-            // 钃濋槦锛氳繑鍥炴垬鍦轰笓灞炵紦瀛�
-            if (!blueTeamAudioCacheDict.ContainsKey(battleGuid))
-            {
-                blueTeamAudioCacheDict[battleGuid] = new Dictionary<string, BattleResCache.CachedResource>();
-            }
-            return blueTeamAudioCacheDict[battleGuid];
-        }
-    }
-    
-    /// <summary>
-    /// 娣诲姞绾㈤槦璧勬簮寮曠敤锛堢敱鍔犺浇鍣ㄨ皟鐢級
-    /// </summary>
-    public void AddRedTeamSpineReference(string key, BattleResCache.CachedResource resource, string ownerId)
-    {
-        if (!globalRedTeamSpineCache.ContainsKey(key))
-        {
-            globalRedTeamSpineCache[key] = new ResourceReference
-            {
-                CachedResource = resource
-            };
-        }
-        globalRedTeamSpineCache[key].AddOwner(ownerId);
-    }
-    
-    /// <summary>
-    /// 娣诲姞绾㈤槦闊抽寮曠敤
-    /// </summary>
-    public void AddRedTeamAudioReference(string key, BattleResCache.CachedResource resource, string ownerId)
-    {
-        if (!globalRedTeamAudioCache.ContainsKey(key))
-        {
-            globalRedTeamAudioCache[key] = new ResourceReference
-            {
-                CachedResource = resource
-            };
-        }
-        globalRedTeamAudioCache[key].AddOwner(ownerId);
-    }
-    
-    /// <summary>
-    /// 鑾峰彇Spine璧勬簮锛堟湭鍛戒腑鏃惰嚜鍔ㄥ姞杞藉苟缂撳瓨锛�
-    /// </summary>
-    public SkeletonDataAsset GetSpineResource(string directory, string assetName, string battleGuid = "", bool autoLoadIfMissing = true)
-    {
-        string key = $"{directory}/{assetName}";
-        
-        // 浼樺厛浠庣孩闃熷叏灞�缂撳瓨鏌ユ壘
-        if (globalRedTeamSpineCache.TryGetValue(key, out var redRef))
-        {
-            return redRef.CachedResource.Asset as SkeletonDataAsset;
-        }
-        
-        // 鍐嶄粠钃濋槦鎴樺満涓撳睘缂撳瓨鏌ユ壘
-        if (!string.IsNullOrEmpty(battleGuid) && blueTeamSpineCacheDict.TryGetValue(battleGuid, out var blueCache))
-        {
-            if (blueCache.TryGetValue(key, out var blueRes))
-            {
-                return blueRes.Asset as SkeletonDataAsset;
-            }
-        }
-        
-        // ===== 缂撳瓨鏈懡涓椂鑷姩鍔犺浇 =====
-        if (autoLoadIfMissing)
-        {
-            Debug.LogWarning($"BattleCacheManager: Spine cache miss for {key}, loading on-demand...");
-            
-            SkeletonDataAsset asset = ResManager.Instance.LoadAsset<SkeletonDataAsset>(directory, assetName);
-            
-            if (asset != null)
-            {
-                var identifier = new BattleResCache.ResourceIdentifier
-                {
-                    Directory = directory,
-                    AssetName = assetName,
-                    Type = BattleResCache.ResourceType.Spine,
-                    IsPersistent = string.IsNullOrEmpty(battleGuid)
-                };
-                
-                var cachedRes = new BattleResCache.CachedResource(identifier, asset, identifier.IsPersistent);
-                
-                if (string.IsNullOrEmpty(battleGuid))
-                {
-                    // 绾㈤槦锛氭坊鍔犲紩鐢紙鏈煡鎵�鏈夎�咃紝鐢ㄧ壒娈婃爣璇嗭級
-                    AddRedTeamSpineReference(key, cachedRes, "OnDemand");
-                    Debug.Log($"BattleCacheManager: Added to global red cache: {key}");
-                }
-                else
-                {
-                    // 钃濋槦锛氱洿鎺ュ姞鍏ユ垬鍦虹紦瀛�
-                    if (!blueTeamSpineCacheDict.ContainsKey(battleGuid))
-                    {
-                        blueTeamSpineCacheDict[battleGuid] = new Dictionary<string, BattleResCache.CachedResource>();
-                    }
-                    blueTeamSpineCacheDict[battleGuid][key] = cachedRes;
-                    Debug.Log($"BattleCacheManager: Added to blue cache (BF={battleGuid}): {key}");
-                }
-                
-                return asset;
-            }
-        }
-        
-        return null;
-    }
-    
-    /// <summary>
-    /// 鑾峰彇闊抽璧勬簮锛堟湭鍛戒腑鏃惰嚜鍔ㄥ姞杞藉苟缂撳瓨锛�
-    /// </summary>
-    public AudioClip GetAudioResource(string directory, string assetName, string battleGuid = "", bool autoLoadIfMissing = true)
-    {
-        string key = $"{directory}/{assetName}";
-        
-        // 浼樺厛浠庣孩闃熷叏灞�缂撳瓨鏌ユ壘
-        if (globalRedTeamAudioCache.TryGetValue(key, out var redRef))
-        {
-            return redRef.CachedResource.Asset as AudioClip;
-        }
-        
-        // 鍐嶄粠钃濋槦鎴樺満涓撳睘缂撳瓨鏌ユ壘
-        if (!string.IsNullOrEmpty(battleGuid) && blueTeamAudioCacheDict.TryGetValue(battleGuid, out var blueCache))
-        {
-            if (blueCache.TryGetValue(key, out var blueRes))
-            {
-                return blueRes.Asset as AudioClip;
-            }
-        }
-        
-        // ===== 缂撳瓨鏈懡涓椂鑷姩鍔犺浇 =====
-        if (autoLoadIfMissing)
-        {
-            Debug.LogWarning($"BattleCacheManager: Audio cache miss for {key}, loading on-demand...");
-            
-            AudioClip asset = ResManager.Instance.LoadAsset<AudioClip>(directory, assetName, false);
-            
-            if (asset != null)
-            {
-                var identifier = new BattleResCache.ResourceIdentifier
-                {
-                    Directory = directory,
-                    AssetName = assetName,
-                    Type = BattleResCache.ResourceType.Audio,
-                    IsPersistent = string.IsNullOrEmpty(battleGuid)
-                };
-                
-                var cachedRes = new BattleResCache.CachedResource(identifier, asset, identifier.IsPersistent);
-                
-                if (string.IsNullOrEmpty(battleGuid))
-                {
-                    // 绾㈤槦锛氭坊鍔犲紩鐢�
-                    AddRedTeamAudioReference(key, cachedRes, "OnDemand");
-                    Debug.Log($"BattleCacheManager: Added to global red audio cache: {key}");
-                }
-                else
-                {
-                    // 钃濋槦锛氱洿鎺ュ姞鍏ユ垬鍦虹紦瀛�
-                    if (!blueTeamAudioCacheDict.ContainsKey(battleGuid))
-                    {
-                        blueTeamAudioCacheDict[battleGuid] = new Dictionary<string, BattleResCache.CachedResource>();
-                    }
-                    blueTeamAudioCacheDict[battleGuid][key] = cachedRes;
-                    Debug.Log($"BattleCacheManager: Added to blue audio cache (BF={battleGuid}): {key}");
-                }
-                
-                return asset;
-            }
-        }
-        
-        return null;
-    }
-    
-    /// <summary>
-    /// 绉婚櫎鎸囧畾瑙掕壊鐨勭孩闃熻祫婧愬紩鐢�
-    /// </summary>
-    public void RemoveRedTeamReferences(List<string> ownerIds)
-    {
-        if (ownerIds == null || ownerIds.Count == 0)
-            return;
-        
-        int removedSpineCount = 0;
-        int removedAudioCount = 0;
-        
-        // 澶勭悊Spine璧勬簮
-        var spineKeysToRemove = new List<string>();
-        foreach (var kvp in globalRedTeamSpineCache)
-        {
-            foreach (var ownerId in ownerIds)
-            {
-                kvp.Value.RemoveOwner(ownerId);
-            }
-            
-            // 濡傛灉娌℃湁寮曠敤浜嗭紝鏍囪鍒犻櫎
-            if (kvp.Value.RefCount == 0)
-            {
-                spineKeysToRemove.Add(kvp.Key);
-            }
-        }
-        
-        foreach (var key in spineKeysToRemove)
-        {
-            var resource = globalRedTeamSpineCache[key].CachedResource;
-            ResManager.Instance.UnloadAsset(
-                resource.Identifier.Directory.ToLower(), 
-                resource.Identifier.AssetName.ToLower()
-            );
-            globalRedTeamSpineCache.Remove(key);
-            removedSpineCount++;
-        }
-        
-        // 澶勭悊闊抽璧勬簮
-        var audioKeysToRemove = new List<string>();
-        foreach (var kvp in globalRedTeamAudioCache)
-        {
-            foreach (var ownerId in ownerIds)
-            {
-                kvp.Value.RemoveOwner(ownerId);
-            }
-            
-            if (kvp.Value.RefCount == 0)
-            {
-                audioKeysToRemove.Add(kvp.Key);
-            }
-        }
-        
-        foreach (var key in audioKeysToRemove)
-        {
-            var resource = globalRedTeamAudioCache[key].CachedResource;
-            ResManager.Instance.UnloadAsset(
-                resource.Identifier.Directory.ToLower(), 
-                resource.Identifier.AssetName.ToLower()
-            );
-            globalRedTeamAudioCache.Remove(key);
-            removedAudioCount++;
-        }
-        
-        Debug.Log($"BattleCacheManager: Removed {ownerIds.Count} owner(s), freed {removedSpineCount} spine + {removedAudioCount} audio resources");
-    }
-    
-    /// <summary>
-    /// 娓呯┖鎸囧畾鎴樺満鐨勮摑闃熺紦瀛�
-    /// </summary>
-    public void ClearBlueTeamCache(string battleGuid)
-    {
-        if (blueTeamSpineCacheDict.ContainsKey(battleGuid))
-        {
-            blueTeamSpineCacheDict.Remove(battleGuid);
-        }
-        
-        if (blueTeamAudioCacheDict.ContainsKey(battleGuid))
-        {
-            blueTeamAudioCacheDict.Remove(battleGuid);
-        }
-        
-        Debug.Log($"BattleCacheManager: Cleared blue team cache for battlefield {battleGuid}");
-    }
-    
-    /// <summary>
-    /// 娓呯┖绾㈤槦鍏ㄥ眬缂撳瓨锛堢帺瀹堕噸缃樀瀹规椂璋冪敤锛�
-    /// </summary>
-    public void ClearRedTeamCache()
-    {
-        globalRedTeamSpineCache.Clear();
-        globalRedTeamAudioCache.Clear();
-        Debug.Log("BattleCacheManager: Cleared red team global cache");
-    }
-    
-    /// <summary>
-    /// 鑾峰彇缂撳瓨缁熻淇℃伅
-    /// </summary>
-    public string GetCacheStats(string battleGuid = "")
-    {
-        int blueSpineCount = blueTeamSpineCacheDict.ContainsKey(battleGuid) ? blueTeamSpineCacheDict[battleGuid].Count : 0;
-        int blueAudioCount = blueTeamAudioCacheDict.ContainsKey(battleGuid) ? blueTeamAudioCacheDict[battleGuid].Count : 0;
-        
-        return $"Red Spine: {globalRedTeamSpineCache.Count}, Red Audio: {globalRedTeamAudioCache.Count}, " +
-               $"Blue Spine (BF={battleGuid}): {blueSpineCount}, Blue Audio (BF={battleGuid}): {blueAudioCount}";
-    }
-    
-    // ========== BattleCacheManager.cs 鏂板鏂规硶 ==========
-
-    /// <summary>
-    /// 璁板綍鎴樺満鐨勭孩闃熻祫婧愰渶姹傦紙澧炲姞寮曠敤锛�
-    /// </summary>
-    public void RegisterBattlefieldRedTeam(string battleGuid, List<BattleResCache.ResourceIdentifier> spineResources, List<BattleResCache.ResourceIdentifier> audioResources)
-    {
-        // 璁板綍杩欎釜鎴樺満浣跨敤鐨勭孩闃熻祫婧愮殑OwnerIds
-        var ownerIds = new HashSet<string>();
-        
+        // 娉ㄥ唽Spine璧勬簮
         foreach (var res in spineResources)
         {
-            if (!string.IsNullOrEmpty(res.OwnerId))
+            if (string.IsNullOrEmpty(res.OwnerId))
+                continue;
+                
+            string key = res.GetKey();
+            
+            if (!globalSpineCache.ContainsKey(key))
             {
-                ownerIds.Add(res.OwnerId);
+                globalSpineCache[key] = new ResourceReference
+                {
+                    CachedResource = new BattleResCache.CachedResource(res, null, false)
+                };
             }
+            
+            globalSpineCache[key].AddBattlefieldOwner(battleGuid, res.OwnerId);
         }
         
+        // 娉ㄥ唽Audio璧勬簮
         foreach (var res in audioResources)
         {
-            if (!string.IsNullOrEmpty(res.OwnerId))
-            {
-                ownerIds.Add(res.OwnerId);
-            }
-        }
-        
-        if (!battlefieldRedTeamOwners.ContainsKey(battleGuid))
-        {
-            battlefieldRedTeamOwners[battleGuid] = ownerIds;
-        }
-    }
-
-    /// <summary>
-    /// 娉ㄩ攢鎴樺満鐨勭孩闃熻祫婧愰渶姹傦紙鍑忓皯寮曠敤锛�
-    /// </summary>
-    public void UnregisterBattlefieldRedTeam(string battleGuid)
-    {
-        if (!battlefieldRedTeamOwners.ContainsKey(battleGuid))
-            return;
+            if (string.IsNullOrEmpty(res.OwnerId))
+                continue;
+                
+            string key = res.GetKey();
             
-        var ownerIds = battlefieldRedTeamOwners[battleGuid];
+            if (!globalAudioCache.ContainsKey(key))
+            {
+                globalAudioCache[key] = new ResourceReference
+                {
+                    CachedResource = new BattleResCache.CachedResource(res, null, false)
+                };
+            }
+            
+            globalAudioCache[key].AddBattlefieldOwner(battleGuid, res.OwnerId);
+        }
         
-        // 浠庢墍鏈夌孩闃熻祫婧愪腑绉婚櫎杩欎簺OwnerIds鐨勫紩鐢�
-        RemoveOwnersFromRedTeamCache(ownerIds);
-        
-        battlefieldRedTeamOwners.Remove(battleGuid);
+        Debug.Log($"BattleCacheManager: Registered battlefield {battleGuid} - Spine: {spineResources.Count}, Audio: {audioResources.Count}");
     }
-
-    private void RemoveOwnersFromRedTeamCache(HashSet<string> ownerIds)
+    
+    /// <summary>
+    /// 娉ㄩ攢鎴樺満锛堝嵏杞借鎴樺満鐨勬墍鏈夎祫婧愬紩鐢級
+    /// </summary>
+    public void UnregisterBattlefield(string battleGuid)
     {
         // 澶勭悊Spine璧勬簮
         var spineKeysToRemove = new List<string>();
-        foreach (var kvp in globalRedTeamSpineCache)
+        foreach (var kvp in globalSpineCache)
         {
-            foreach (var ownerId in ownerIds)
-            {
-                kvp.Value.RemoveOwner(ownerId);
-            }
+            kvp.Value.RemoveBattlefield(battleGuid);
             
-            // 寮曠敤璁℃暟涓�0鏃剁湡姝e嵏杞�
             if (kvp.Value.RefCount == 0)
             {
                 spineKeysToRemove.Add(kvp.Key);
@@ -430,20 +122,23 @@
         
         foreach (var key in spineKeysToRemove)
         {
-            var res = globalRedTeamSpineCache[key];
-            ResManager.Instance.UnloadAsset(res.CachedResource.Identifier.Directory, res.CachedResource.Identifier.AssetName);
-            globalRedTeamSpineCache.Remove(key);
-            Debug.Log($"BattleCacheManager: Unloaded red team spine (refCount=0): {key}");
+            var res = globalSpineCache[key];
+            if (res.CachedResource.Asset != null)
+            {
+                ResManager.Instance.UnloadAsset(
+                    res.CachedResource.Identifier.Directory, 
+                    res.CachedResource.Identifier.AssetName
+                );
+            }
+            globalSpineCache.Remove(key);
+            Debug.Log($"BattleCacheManager: Unloaded spine (refCount=0): {key}");
         }
         
         // 澶勭悊Audio璧勬簮
         var audioKeysToRemove = new List<string>();
-        foreach (var kvp in globalRedTeamAudioCache)
+        foreach (var kvp in globalAudioCache)
         {
-            foreach (var ownerId in ownerIds)
-            {
-                kvp.Value.RemoveOwner(ownerId);
-            }
+            kvp.Value.RemoveBattlefield(battleGuid);
             
             if (kvp.Value.RefCount == 0)
             {
@@ -453,10 +148,115 @@
         
         foreach (var key in audioKeysToRemove)
         {
-            var res = globalRedTeamAudioCache[key];
-            ResManager.Instance.UnloadAsset(res.CachedResource.Identifier.Directory, res.CachedResource.Identifier.AssetName);
-            globalRedTeamAudioCache.Remove(key);
-            Debug.Log($"BattleCacheManager: Unloaded red team audio (refCount=0): {key}");
+            var res = globalAudioCache[key];
+            if (res.CachedResource.Asset != null)
+            {
+                ResManager.Instance.UnloadAsset(
+                    res.CachedResource.Identifier.Directory, 
+                    res.CachedResource.Identifier.AssetName
+                );
+            }
+            globalAudioCache.Remove(key);
+            Debug.Log($"BattleCacheManager: Unloaded audio (refCount=0): {key}");
         }
+        
+        Debug.Log($"BattleCacheManager: Unregistered battlefield {battleGuid}");
+    }
+    
+    /// <summary>
+    /// 鑾峰彇鎴栧姞杞絊pine璧勬簮
+    /// </summary>
+    public SkeletonDataAsset GetSpineResource(string directory, string assetName, string battleGuid = "")
+    {
+        string key = $"{directory}/{assetName}";
+        
+        if (globalSpineCache.TryGetValue(key, out var refInfo))
+        {
+            return refInfo.CachedResource.Asset as SkeletonDataAsset;
+        }
+        
+        // 鑷姩鍔犺浇
+        Debug.LogWarning($"BattleCacheManager: Spine cache miss for {key}, loading on-demand...");
+        var asset = ResManager.Instance.LoadAsset<SkeletonDataAsset>(directory, assetName);
+        
+        if (asset != null)
+        {
+            var identifier = new BattleResCache.ResourceIdentifier
+            {
+                Directory = directory,
+                AssetName = assetName,
+                Type = BattleResCache.ResourceType.Spine
+            };
+            
+            globalSpineCache[key] = new ResourceReference
+            {
+                CachedResource = new BattleResCache.CachedResource(identifier, asset, false)
+            };
+        }
+        
+        return asset;
+    }
+    
+    /// <summary>
+    /// 鑾峰彇鎴栧姞杞紸udio璧勬簮
+    /// </summary>
+    public AudioClip GetAudioResource(string directory, string assetName, string battleGuid = "")
+    {
+        string key = $"{directory}/{assetName}";
+        
+        if (globalAudioCache.TryGetValue(key, out var refInfo))
+        {
+            return refInfo.CachedResource.Asset as AudioClip;
+        }
+        
+        // 鑷姩鍔犺浇
+        Debug.LogWarning($"BattleCacheManager: Audio cache miss for {key}, loading on-demand...");
+        var asset = ResManager.Instance.LoadAsset<AudioClip>(directory, assetName, false);
+        
+        if (asset != null)
+        {
+            var identifier = new BattleResCache.ResourceIdentifier
+            {
+                Directory = directory,
+                AssetName = assetName,
+                Type = BattleResCache.ResourceType.Audio
+            };
+            
+            globalAudioCache[key] = new ResourceReference
+            {
+                CachedResource = new BattleResCache.CachedResource(identifier, asset, false)
+            };
+        }
+        
+        return asset;
+    }
+    
+    /// <summary>
+    /// 鏇存柊宸插姞杞借祫婧愮殑寮曠敤锛堢敱鍔犺浇鍣ㄨ皟鐢級
+    /// </summary>
+    public void UpdateResourceReference(string key, BattleResCache.CachedResource resource, string battleGuid, string ownerId)
+    {
+        if (resource.Identifier.Type == BattleResCache.ResourceType.Spine)
+        {
+            if (globalSpineCache.ContainsKey(key))
+            {
+                globalSpineCache[key].CachedResource = resource;
+            }
+        }
+        else if (resource.Identifier.Type == BattleResCache.ResourceType.Audio)
+        {
+            if (globalAudioCache.ContainsKey(key))
+            {
+                globalAudioCache[key].CachedResource = resource;
+            }
+        }
+    }
+    
+    public string GetCacheStats(string battleGuid = "")
+    {
+        int spineTotal = globalSpineCache.Count;
+        int audioTotal = globalAudioCache.Count;
+        
+        return $"Spine: {spineTotal}, Audio: {audioTotal}";
     }
 }
\ No newline at end of file

--
Gitblit v1.8.0