Main/System/Battle/BattleResources/BattleCacheManager.cs
@@ -39,6 +39,10 @@
    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>
@@ -357,4 +361,102 @@
        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>();
        foreach (var res in spineResources)
        {
            if (!string.IsNullOrEmpty(res.OwnerId))
            {
                ownerIds.Add(res.OwnerId);
            }
        }
        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;
        var ownerIds = battlefieldRedTeamOwners[battleGuid];
        // 从所有红队资源中移除这些OwnerIds的引用
        RemoveOwnersFromRedTeamCache(ownerIds);
        battlefieldRedTeamOwners.Remove(battleGuid);
    }
    private void RemoveOwnersFromRedTeamCache(HashSet<string> ownerIds)
    {
        // 处理Spine资源
        var spineKeysToRemove = new List<string>();
        foreach (var kvp in globalRedTeamSpineCache)
        {
            foreach (var ownerId in ownerIds)
            {
                kvp.Value.RemoveOwner(ownerId);
            }
            // 引用计数为0时真正卸载
            if (kvp.Value.RefCount == 0)
            {
                spineKeysToRemove.Add(kvp.Key);
            }
        }
        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}");
        }
        // 处理Audio资源
        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 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}");
        }
    }
}