yyl
2026-05-11 51b0f6ed9f4e1d3bb6f8144470b46908c7699a96
Main/System/Battle/BattleObject/BattleObjMgr.cs
@@ -3,48 +3,215 @@
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using Cysharp.Threading.Tasks;
public class BattleObjMgr
{
    //  死亡不可以将BattleObject移出字典/列表
    public List<BattleObject> redCampList => new List<BattleObject>(redCampDict.Values);
    public List<BattleObject> blueCampList => new List<BattleObject>(blueCampDict.Values);
    // 缓存阵营列表,仅在字典变更时重建,避免每次属性访问分配新List
    private List<BattleObject> _redCampListCache;
    private List<BattleObject> _blueCampListCache;
    private bool _redCampDirty = true;
    private bool _blueCampDirty = true;
    public List<BattleObject> redCampList
    {
        get
        {
            if (_redCampDirty || _redCampListCache == null)
            {
                if (_redCampListCache == null) _redCampListCache = new List<BattleObject>(redCampDict.Count);
                else _redCampListCache.Clear();
                foreach (var kv in redCampDict) _redCampListCache.Add(kv.Value);
                _redCampDirty = false;
            }
            return _redCampListCache;
        }
    }
    public List<BattleObject> blueCampList
    {
        get
        {
            if (_blueCampDirty || _blueCampListCache == null)
            {
                if (_blueCampListCache == null) _blueCampListCache = new List<BattleObject>(blueCampDict.Count);
                else _blueCampListCache.Clear();
                foreach (var kv in blueCampDict) _blueCampListCache.Add(kv.Value);
                _blueCampDirty = false;
            }
            return _blueCampListCache;
        }
    }
    private Dictionary<int, BattleObject> redCampDict = new Dictionary<int, BattleObject>();
    private Dictionary<int, BattleObject> blueCampDict = new Dictionary<int, BattleObject>();
    protected Dictionary<int, BattleObject> allBattleObjDict = new Dictionary<int, BattleObject>();
    public Dictionary<int, BattleObject> allBattleObjDict = new Dictionary<int, BattleObject>();
    public MinggeBattleObject redMingge = null;
    public MinggeBattleObject blueMingge = null;
    protected BattleField battleField;
    public void Init(BattleField _battleField, TeamBase _redTeam, TeamBase _blueTeam)
    public async UniTask Init(BattleField _battleField, TeamBase _redTeam, TeamBase _blueTeam)
    {
        battleField = _battleField;
        CreateTeam(battleField.battleRootNode.redTeamNodeList, redCampDict, _redTeam, BattleCamp.Red);
        CreateTeam(battleField.battleRootNode.blueTeamNodeList, blueCampDict, _blueTeam, BattleCamp.Blue);
    }
        await Reload(_battleField, _redTeam, _blueTeam);
    }
    protected void CreateTeam(List<GameObject> posNodeList, Dictionary<int, BattleObject> campDict, TeamBase teamBase, BattleCamp _Camp)
    public async UniTask Reload(BattleField _battleField, TeamBase _redTeam, TeamBase _blueTeam)
    {
        Release();
        battleField = _battleField;
        await ReloadTeam(_redTeam, BattleCamp.Red);
        await ReloadTeam(_blueTeam, BattleCamp.Blue, false);    }
    public async UniTask ReloadTeam(TeamBase teamBase, BattleCamp _camp, bool active = true)
    {
        var posNodeList = _camp == BattleCamp.Red ? battleField.battleRootNode.redTeamNodeList : battleField.battleRootNode.blueTeamNodeList;
        var campDict = _camp == BattleCamp.Red ? redCampDict : blueCampDict;
        await CreateTeam(posNodeList, campDict, teamBase, _camp, active);
    }
    private void MarkCampDirty(Dictionary<int, BattleObject> campDict)
    {
        if (campDict == redCampDict) _redCampDirty = true;
        else if (campDict == blueCampDict) _blueCampDirty = true;
    }
    protected async UniTask CreateTeam(List<GameObject> posNodeList, Dictionary<int, BattleObject> campDict, TeamBase teamBase, BattleCamp _Camp, bool active)
    {
        DestroyTeam(campDict);
        for (int i = 0; i < teamBase.teamHeros.Length; i++)
        if (teamBase == null)
        {
            TeamHero teamHero = teamBase.teamHeros[i];
            return;
        }
        for (int i = 0; i < teamBase.serverHeroes.Length; i++)
        {
            TeamHero teamHero = teamBase.serverHeroes[i];
            if (teamHero != null)
            {
                BattleObject battleObj = BattleObjectFactory.CreateBattleObject(battleField, posNodeList, teamHero, _Camp);
                allBattleObjDict.Add(battleObj.BattleObjectId, battleObj);
                campDict.Add(teamHero.heroIndex, battleObj);
                BattleObject battleObj = await BattleObjectFactory.CreateBattleObjectAsync(battleField, posNodeList, teamHero, _Camp);
                battleObj.SetActive(active);
                allBattleObjDict.Add(battleObj.ObjID, battleObj);
                campDict.Add(battleObj.GetPositionNum(), battleObj);
                battleObj.SetSpeedRatio(battleField.speedRatio);
            }
        }
        MarkCampDirty(campDict);
        if (teamBase.teamMingge != null)
        {
            BattleObject minggeObj = BattleObjectFactory.CreateMinggeBattleObject(battleField, teamBase, _Camp);
            allBattleObjDict.Add(minggeObj.ObjID, minggeObj);
            campDict.Add(minggeObj.GetPositionNum(), minggeObj);
            minggeObj.SetSpeedRatio(battleField.speedRatio);
            if (_Camp == BattleCamp.Red)
            {
                redMingge = minggeObj as MinggeBattleObject;
            }
            else
            {
                blueMingge = minggeObj as MinggeBattleObject;
            }
        }
    }
    
    public BattleObject GetBattleObject(int battleObjId)
    public BattleObject GetBattleObject(int objId)
    {
        if (allBattleObjDict.TryGetValue(battleObjId, out BattleObject battleObj))
        if (allBattleObjDict.TryGetValue(objId, out BattleObject battleObj))
        {
            return battleObj;
        }
        if (blueMingge != null && blueMingge.ObjID == objId)
        {
            return blueMingge;
        }
        if (redMingge != null && redMingge.ObjID == objId)
        {
            return redMingge;
        }
        return null;
    }
    public MinggeBattleObject GetMinggeBattleObject(BattleCamp camp)
    {
        if (camp == BattleCamp.Red)
        {
            return redMingge;
        }
        else
        {
            return blueMingge;
        }
    }
    public List<BattleObject> GetBattleObjList(BattleCamp _Camp)
    {
        if (_Camp == BattleCamp.Red)
        {
            return redCampList;
        }
        else
        {
            return blueCampList;
        }
    }
    public List<BattleObject> GetBattleObjList(HB427_tagSCUseSkill tagUseSkillAttack)
    {
        List<BattleObject> retList = new List<BattleObject>();
        foreach (var hurt in tagUseSkillAttack.HurtList)
        {
            BattleObject obj = GetBattleObject((int)hurt.ObjID);
            if (null != obj)
            {
                retList.Add(obj);
            }
        }
        return retList;
    }
    public void DestroyTeam(BattleCamp battleCamp)
    {
        Dictionary<int, BattleObject> campDict = battleCamp == BattleCamp.Red ? redCampDict : blueCampDict;
        if (campDict == null)
        {
            return;
        }
        DestroyTeam(campDict);
    }
    public void DestroyObjIds(uint[] objIDs)
    {
        if (objIDs == null || objIDs.Length == 0)
        {
            return;
        }
        foreach (var objID in objIDs)
        {
            if (allBattleObjDict.TryGetValue((int)objID, out BattleObject battleObj))
            {
                if (battleObj.Camp == BattleCamp.Red)
                {
                    redCampDict.Remove(battleObj.GetPositionNum());
                    _redCampDirty = true;
                }
                else
                {
                    blueCampDict.Remove(battleObj.GetPositionNum());
                    _blueCampDirty = true;
                }
                allBattleObjDict.Remove((int)objID);
                BattleObjectFactory.DestroyBattleObject((int)objID, battleObj);
            }
        }
    }
    protected void DestroyTeam(Dictionary<int, BattleObject> campDict)
@@ -52,20 +219,44 @@
        foreach (var item in campDict)
        {
            BattleObject battleObj = item.Value;
            var positionNum = item.Key;
            if (battleObj != null)
            {
                allBattleObjDict.Remove(battleObj.BattleObjectId);
                BattleObjectFactory.DestroyBattleObject(item.Key, battleObj);
                allBattleObjDict.Remove(battleObj.ObjID);
                BattleObjectFactory.DestroyBattleObject(battleObj.ObjID, battleObj);
            }
        }
        campDict.Clear();
        MarkCampDirty(campDict);
    }
    public void Release()
    //  空闲状态
    public virtual void HaveRest(BattleCamp _Camp)
    {
        //  休息状态
        if (_Camp == BattleCamp.Red)
        {
            foreach (var item in redCampDict.Values)
            {
                item.HaveRest();
            }
        }
        else
        {
            foreach (var item in blueCampDict.Values)
            {
                item.HaveRest();
            }
        }
    }
    public virtual void Release()
    {
        DestroyTeam(redCampDict);
        DestroyTeam(blueCampDict);
        allBattleObjDict.Clear();
        redMingge = null;
        blueMingge = null;
    }
    public void Run()
@@ -127,7 +318,29 @@
        return blueCampList;
    }
#if UNITY_EDITOR
    public BattleObject GetBattleObjectByIndex(BattleCamp camp, int selfIndex)
    {
        if (camp == BattleCamp.Red)
        {
            redCampDict.TryGetValue(selfIndex, out BattleObject battleObj);
            return battleObj;
        }
        else
        {
            blueCampDict.TryGetValue(selfIndex, out BattleObject battleObj);
            return battleObj;
        }
    }
    public void SetSpeedRatio(float ratio)
    {
        foreach (var obj in allBattleObjDict.Values)
        {
            obj.SetSpeedRatio(ratio);
        }
    }
#if UNITY_EDITOR_STOP_USING
    public void ReviveAll()
    {
        foreach (var kv in allBattleObjDict)
@@ -168,7 +381,7 @@
                //暂时没有召唤物
                // 放在第7格的BOSS后排的。。位置放在正中间
                // a)前排,1、2、3号为前排,前排全部阵亡后,4、5、6号即是前排也是后排 7其实也是后排
                List<BattleObject> frontList = new List<BattleObject>(from BO in returnList where BO.teamHero.heroIndex < 3 && !BO.IsDead() select BO);
                List<BattleObject> frontList = new List<BattleObject>(from BO in returnList where BO.GetPositionNum() < 3 && !BO.IsDead() select BO);
                if (frontList.Count == 0)
                {
                    frontList.AddRange(returnList);
@@ -176,7 +389,7 @@
                returnList = frontList;                
                break;
            case SkillTargetRangeType.Back:
                List<BattleObject> backList = new List<BattleObject>(from BO in returnList where BO.teamHero.heroIndex >= 3 && !BO.IsDead() select BO);
                List<BattleObject> backList = new List<BattleObject>(from BO in returnList where BO.GetPositionNum() >= 3 && !BO.IsDead() select BO);
                if (backList.Count == 0)
                {
                    backList.AddRange(returnList);
@@ -198,18 +411,8 @@
            case SkillTargetRangeType.HighestAttack:
                returnList = new List<BattleObject>(from BO in returnList where !BO.IsDead() select BO);
                BattleObject mostHighestAttckObj = null;
                for (int i = 0; i < returnList.Count; i++)
                {
                    if (mostHighestAttckObj == null)
                    {
                        mostHighestAttckObj = returnList[i];
                        continue;
                    }
                    if (returnList[i].teamHero.attack > mostHighestAttckObj.teamHero.attack)
                    {
                        mostHighestAttckObj = returnList[i];
                    }
                }
                //  客户端不包含数据 这里取第一个
                mostHighestAttckObj = returnList[0];
                returnList.Clear();
                if (mostHighestAttckObj != null)
                    returnList.Add(mostHighestAttckObj);
@@ -224,7 +427,7 @@
                        loweastHpObj = returnList[i];
                        continue;
                    }
                    if (returnList[i].teamHero.curHp < loweastHpObj.teamHero.curHp)
                    if (returnList[i].GetCurHp() < loweastHpObj.GetCurHp())
                    {
                        loweastHpObj = returnList[i];
                    }