125 战斗 预加载资源 解决新战场出现时会卸载旧战场红队资源的问题
3个文件已修改
140 ■■■■ 已修改文件
Main/System/Battle/BattleResources/BattleCacheManager.cs 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleResources/BattlePreloadManager.cs 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleResources/BattleUnloadManager.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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}");
        }
    }
}
Main/System/Battle/BattleResources/BattlePreloadManager.cs
@@ -31,6 +31,9 @@
        var redTeamInfo = AnalyzeTeamList(redTeamList, true);
        var blueTeamInfo = AnalyzeTeamList(blueTeamList, false);
        
        // ===== 新增:注册战场红队资源需求 =====
        cacheManager.RegisterBattlefieldRedTeam(battleGuid, redTeamInfo.SpineResources, redTeamInfo.AudioResources);
        StartPreload(redTeamInfo, blueTeamInfo, battleGuid, progressCallback, () =>
        {
            isLoading = false;
@@ -161,28 +164,5 @@
            null,   // ← 蓝队不需要引用追踪
            false   // ← 不是红队
        );
    }
    /// <summary>
    /// 处理红队变更:清空旧的,重新加载新的
    /// </summary>
    public void HandleRedTeamChange(List<TeamBase> newRedTeamList, Action completeCallback)
    {
        if (newRedTeamList == null)
        {
            completeCallback?.Invoke();
            return;
        }
        Debug.Log("BattlePreloadManager: Handling red team change");
        // 1. 卸载旧的红队资源
        unloadManager.UnloadRedTeamResources(cacheManager);
        // 2. 分析新红队资源
        var newRedInfo = AnalyzeTeamList(newRedTeamList, true);
        // 3. 预加载新红队资源(红队是全局的,传空字符串)
        StartPreload(newRedInfo, new TeamResTracker.TeamResourceInfo(), "", null, completeCallback);
    }
}
Main/System/Battle/BattleResources/BattleUnloadManager.cs
@@ -88,4 +88,16 @@
        
        Debug.Log("BattleUnloadManager: All resources unloaded");
    }
    /// <summary>
    /// 卸载战场资源
    /// </summary>
    public void UnloadBattleResources(BattleCacheManager cacheManager, string battleGuid)
    {
        // 卸载蓝队资源
        UnloadBlueTeamResources(cacheManager, battleGuid);
        // ===== 新增:注销战场红队引用(自动按引用计数卸载)=====
        cacheManager.UnregisterBattlefieldRedTeam(battleGuid);
    }
}