using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using BaseGames.Core; using BaseGames.Core.Events; namespace BaseGames.World.Map { /// /// 全屏地图 UI 面板(架构 15_MapShopModule §1.3)。 /// 由 UIManager PanelStack 管理开关;OnEnable 时重建格子并订阅更新事件。 /// public class MapPanel : MonoBehaviour { [SerializeField] private MapDatabaseSO _database; [SerializeField] private RectTransform _roomContainer; // 格子图放置根节点 [SerializeField] private MapRoomCellUI _cellPrefab; // 地图格子预制 [Header("图标 Sprites")] [SerializeField] private Sprite _iconSavePoint; [SerializeField] private Sprite _iconBossRoom; [SerializeField] private Sprite _iconShop; [SerializeField] private Sprite _iconPlayerPos; [Header("颜色")] [SerializeField] private Color _colorDiscovered = Color.white; [SerializeField] private Color _colorUndiscovered = Color.black; [Header("Event Channels")] [SerializeField] private StringEventChannelSO _onMapUpdated; // 房间发现时刷新 private Dictionary _cells = new(); private readonly CompositeDisposable _subs = new(); private void OnEnable() { BuildGrid(); _onMapUpdated?.Subscribe(OnMapUpdated).AddTo(_subs); } private void OnDisable() { _subs.Clear(); // 清理动态生成的格子 foreach (var cell in _cells.Values) if (cell != null) Destroy(cell.gameObject); _cells.Clear(); } // ── 内部 ────────────────────────────────────────────────────────────── private void BuildGrid() { if (_database == null || _database.AllRooms == null) return; var mapManager = ServiceLocator.GetOrDefault(); foreach (var room in _database.AllRooms) { if (room == null) continue; var cell = Instantiate(_cellPrefab, _roomContainer); bool discovered = mapManager != null && mapManager.IsExplored(room.RoomId); cell.Setup(room, discovered, ChooseIcon(room)); _cells[room.RoomId] = cell; } } private void OnMapUpdated(string roomId) { if (_cells.TryGetValue(roomId, out var cell)) cell.SetDiscovered(true); } private Sprite ChooseIcon(MapRoomDataSO room) { if (room.MapIconOverride != null) return room.MapIconOverride; if (room.IsSavePoint) return _iconSavePoint; if (room.IsBossRoom) return _iconBossRoom; if (room.IsShop) return _iconShop; return null; } } // ─── 单个地图格子 UI ───────────────────────────────────────────────────────── /// 地图面板中每个房间对应的格子 UI 组件。 public class MapRoomCellUI : MonoBehaviour { [SerializeField] private Image _bg; [SerializeField] private Image _icon; private static readonly Color Discovered = Color.white; private static readonly Color Undiscovered = Color.black; /// 初始化格子(位置、颜色、图标)。 public void Setup(MapRoomDataSO room, bool discovered, Sprite icon) { // 根据 GridPosition/GridSize 设置 RectTransform 位置与大小 if (TryGetComponent(out var rt)) { rt.anchoredPosition = new Vector2( room.GridPosition.x * 32f, room.GridPosition.y * 32f); rt.sizeDelta = new Vector2( room.GridSize.x * 32f, room.GridSize.y * 32f); } SetDiscovered(discovered); if (_icon != null) { _icon.sprite = icon; _icon.enabled = icon != null; } } public void SetDiscovered(bool v) { if (_bg != null) _bg.color = v ? Discovered : Undiscovered; } } }