using cfg.AreaCfg; using Framework; using Gameplay.Level; using System; using System.Collections.Generic; using Gameplay.Area.Ready; using Gameplay.Unit; using UnityEngine; namespace Gameplay.Area { using Common; using Skill; public class AreaManager { public static bool ENABLE_LOG = false; private static AreaManager _instance; public static AreaManager instance { get { return _instance; } } public static void CreateInstance() { if (_instance != null) { DebugUtil.LogError("请勿重复创建AreaManager"); return; } _instance = new AreaManager(); } private readonly Dictionary> _areaDict; private readonly SkillAreaSelecter _skillAreaSelecter; private readonly Dictionary> _cellIndex2Units; private Map _map; private readonly RoadLineView _roadLine; private readonly AttackAreaView _attackArea; public readonly ReadyAreaManager readyAreaManager; public bool isInSelecting { get { return _skillAreaSelecter.isOnSelecting; } } private AreaManager() { _areaDict = new Dictionary>(); _skillAreaSelecter = new SkillAreaSelecter(); _cellIndex2Units = new Dictionary>(); _roadLine = new RoadLineView(); _attackArea = new AttackAreaView(); _map = LevelManager.Instance.CurrentLevel.Map; readyAreaManager = new ReadyAreaManager(_map); } public void Init() { // 这里要不要做预加载 _roadLine.Init(); _skillAreaSelecter.Init(); _attackArea.Init(); _RegistEvents(); } private void _RegistEvents() { EventManager.Instance.Register(EventManager.EventName.UI_START_USE_SKILL, (Action)_OnPreUseSkill); EventManager.Instance.Register(EventManager.EventName.UI_END_USE_SKILL, (Action)_OnEndUseSkill); EventManager.Instance.Register(EventManager.EventName.INFIGHT_UNIT_READY, (Action)_OnUnitReady); EventManager.Instance.Register(EventManager.EventName.INFIGHT_UNIT_REMOVE, (Action)_OnUnitRemove); EventManager.Instance.Register(EventManager.EventName.INFIGHT_UNIT_CELLINDEX_CHANGE, (Action)_OnUnitCellChange); EventManager.Instance.Register(EventManager.EventName.LevelUnitSelect, (Action)_OnSelectCharacter); EventManager.Instance.Register(EventManager.EventName.LevelUnitUnSelect, (Action)_OnUnSelectCharacter); EventManager.Instance.Register(EventManager.EventName.INFIGHT_UP_VEHICLE, (Action)_OnUpVehicle); EventManager.Instance.Register(EventManager.EventName.INFIGHT_DOWN_VEHICLE, (Action)_OnDownVehicle); } private void _UnRegistEvents() { EventManager.Instance.Unregister(EventManager.EventName.UI_START_USE_SKILL, (Action)_OnPreUseSkill); EventManager.Instance.Unregister(EventManager.EventName.UI_END_USE_SKILL, (Action)_OnEndUseSkill); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UNIT_READY, (Action)_OnUnitReady); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UNIT_REMOVE, (Action)_OnUnitRemove); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UNIT_CELLINDEX_CHANGE, (Action)_OnUnitCellChange); EventManager.Instance.Unregister(EventManager.EventName.LevelUnitSelect, (Action)_OnSelectCharacter); EventManager.Instance.Unregister(EventManager.EventName.LevelUnitUnSelect, (Action)_OnUnSelectCharacter); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UP_VEHICLE, (Action)_OnUpVehicle); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_DOWN_VEHICLE, (Action)_OnDownVehicle); } private void _OnUpVehicle(GameUnit unit) { var cellIndex = unit.transData.cellIndex; // 设置地图通行状态 _map.GetRuntimeBlockProperty(cellIndex, out var oldData); var blockData = _map.GetBlockData(cellIndex); oldData.crossLevel = blockData.GetTerrainTypeProperty().crossLevel; _map.SetRuntimeBlockProperty(cellIndex, oldData); // 移除角色 var unitList = _cellIndex2Units[cellIndex]; unitList.Remove(unit); if (DebugUtil.LogEnable) _Log($"Unit: {unit.GetID()} Up Vehicle at:{cellIndex}"); } private void _OnDownVehicle(GameUnit unit) { var bornCellIndex = unit.transData.cellIndex; if (DebugUtil.LogEnable) _Log($"Unit: {unit.GetID()} Down Vehicle at:{bornCellIndex}"); _AddUnitToCellIndex(bornCellIndex, unit); } private void _OnSelectCharacter(GameUnit c) { _roadLine.UpdateLine(c); _attackArea.SetOwner(c); } private void _OnUnSelectCharacter(GameUnit c) { _roadLine.HideLine(); _attackArea.HideArea(); } private void _OnUnitReady(GameUnit unit) { var bornCellIndex = unit.transData.cellIndex; if (DebugUtil.LogEnable) _Log($"Unit: {unit.GetID()} Ready at: {bornCellIndex}"); _AddUnitToCellIndex(bornCellIndex, unit); } private void _AddUnitToCellIndex(int cellIndex, GameUnit unit) { // 设置地图通行状态 // >0 才进行设置 if (unit.commonData.standLevel > 0) { _map.GetRuntimeBlockProperty(cellIndex, out var setData); setData.crossLevel = unit.commonData.standLevel; _map.SetRuntimeBlockProperty(cellIndex, setData); } if (_cellIndex2Units.TryGetValue(cellIndex, out var unitList)) { unitList.Add(unit); } else { unitList = new List(); unitList.Add(unit); _cellIndex2Units.Add(cellIndex, unitList); } } private void _OnUnitRemove(GameUnit unit) { var cellIndex = unit.transData.cellIndex; if (DebugUtil.LogEnable) _Log($"Unit: {unit.GetID()} Remove at: {cellIndex}"); // 这里必须能去到,所以不用tryget, 如果报错 需要排查上游 if (unit.commonData.standLevel > 0) { // 设置地图通行状态 _map.GetRuntimeBlockProperty(cellIndex, out var oldData); var blockData = _map.GetBlockData(cellIndex); oldData.crossLevel = blockData.GetTerrainTypeProperty().crossLevel; _map.SetRuntimeBlockProperty(cellIndex, oldData); } var unitList = _cellIndex2Units[cellIndex]; unitList.Remove(unit); } private void _OnUnitCellChange(GameUnit unit) { var lastCellIndex = unit.transData.lastCellIndex; var newCellIndex = unit.transData.cellIndex; if (lastCellIndex != -1) { // 设置地图通行状态 if (unit.commonData.standLevel > 0) { _map.GetRuntimeBlockProperty(lastCellIndex, out var oldData); var blockData = _map.GetBlockData(lastCellIndex); oldData.crossLevel = blockData.GetTerrainTypeProperty().crossLevel; _map.SetRuntimeBlockProperty(lastCellIndex, oldData); } // 移除旧的 var unitList = _cellIndex2Units[lastCellIndex]; unitList.Remove(unit); } // 添加新的 _AddUnitToCellIndex(newCellIndex, unit); if (DebugUtil.LogEnable) _Log($"Unit CellIndexChange:{unit.GetID()} from:{lastCellIndex} to {newCellIndex}"); } private static void _Log(string str) { if (!ENABLE_LOG) return; DebugUtil.Log("[AreaManager] {0}", str); } public void Dispose() { _skillAreaSelecter.Dispose(); _roadLine.Dispose(); _UnRegistEvents(); _instance = null; } public DataArea GetConfigById(int areaId) { return TableManager.Instance.Tables.AreaConfig.Get(areaId); } public List GetCellIndexsAround(int centerCellIndex, int distance) { var list = _map.TerrainGridSystem.CellGetNeighboursWithinRange(centerCellIndex, 0, distance, canCrossCheckType: TGS.CanCrossCheckType.IgnoreCanCrossCheckOnAllCells); list.Add(centerCellIndex); return list; } public bool IsCellEmpty(int cellIndex) { var unitList = GetUnitsByCellIndex(cellIndex); return unitList.Count == 0; } public int GetDistance(int cellIndex1, int cellIndex2) { return _map.TerrainGridSystem.CellGetHexagonDistance(cellIndex1, cellIndex2); } public Vector3 GetCellPosByIndex(int cellIndex) { var getPos = _map.TerrainGridSystem.CellGetPosition(cellIndex); return getPos; } public bool CheckIsNeighbour(int fromIndex, int checkIndex) { var aroundList = _map.TerrainGridSystem.CellGetNeighbours(fromIndex); for (var i = 0; i < aroundList.Count; i++) { var around = aroundList[i]; if (around.index == checkIndex) { return true; } } return false; } public List GetCellIndexs(int centerCellIndex, int areaId) { var list = new List(); GetCellIndexs(centerCellIndex, areaId, list); return list; } public void GetCellIndexs(int centerCellIndex, int areaId, List list) { var map = LevelManager.Instance.CurrentLevel.Map; var posVec = map.TGSCellIndex2BlockPosition(centerCellIndex); var offsetList = _GetOffsetList(areaId); for (var i = 0; i < offsetList.Count; ++i) { var offset = offsetList[i]; var calcPos = posVec + offset; if (posVec.x % 2 == 1 && calcPos.x % 2 == 0) { calcPos.y += 1; } var cellIndex = map.BlockPosition2TGSCellIndex(calcPos); list.Add(cellIndex); } } private List _GetOffsetList(int areaId) { if (_areaDict.TryGetValue(areaId, out var offsetList)) { return offsetList; } else { // 不存在,现场进行加载 var DataAreaConfig = GetConfigById(areaId); if (DataAreaConfig == null) { DebugUtil.LogError("AreaId:{0}不存在", areaId); return null; } offsetList = new List(); var intList = DataAreaConfig.Points; for (int i = 0; i < intList.Count; i += 2) { offsetList.Add(new Vector2Int(intList[i], intList[i + 1])); } _areaDict.Add(areaId, offsetList); return offsetList; } } private void _OnPreUseSkill(GameUnit unit) { var skillUnit = SkillManager.instance.GetUnitSkillManager(unit); if (skillUnit == null) { DebugUtil.LogError("Unit:{0} 未挂载UnitSkillManager", unit.GetID()); return; } if (skillUnit.positiveSkill == null) { DebugUtil.LogError("Unit:{0} 未挂载PositiveSkill", unit.GetID()); return; } _attackArea.ForceHide(); _skillAreaSelecter.ShowArea(skillUnit.positiveSkill); } private void _OnEndUseSkill(bool isCancel) { if (DebugUtil.LogEnable) DebugUtil.Log("UI事件: 结束技能预选: 是否cancel:{0}", isCancel); _attackArea.CancelForce(); _skillAreaSelecter.EndShow(!isCancel); } public void LogicUpdate(float dt) { _skillAreaSelecter.LogicUpdate(dt); _roadLine.LogicUpdate(dt); _attackArea.LogicUpdate(dt); readyAreaManager.LogicUpdate(dt); } public List GetUnitsByCellIndex(int cellIndex) { if (_cellIndex2Units.TryGetValue(cellIndex, out var result)) { return result; } else { var newList = new List(); _cellIndex2Units.Add(cellIndex, newList); return newList; } } } }