摄像机区域的架构改动
This commit is contained in:
144
Assets/_Game/Scripts/World/Map/MapPanel.cs
Normal file
144
Assets/_Game/Scripts/World/Map/MapPanel.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using BaseGames.Core;
|
||||
using BaseGames.Core.Events;
|
||||
|
||||
namespace BaseGames.World.Map
|
||||
{
|
||||
/// <summary>
|
||||
/// 全屏地图 UI 面板(架构 15_MapShopModule §1.3)。
|
||||
/// 由 UIManager PanelStack 管理开关;OnEnable 时重建格子并订阅更新事件。
|
||||
/// </summary>
|
||||
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<string, MapRoomCellUI> _cells = new();
|
||||
private readonly CompositeDisposable _subs = new();
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
// 首次打开时建立格子;后续打开只刷新探索状态,跳过 N 次 Instantiate
|
||||
if (_cells.Count == 0)
|
||||
BuildGrid();
|
||||
else
|
||||
RefreshAllCells();
|
||||
|
||||
_onMapUpdated?.Subscribe(OnMapUpdated).AddTo(_subs);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
_subs.Clear();
|
||||
// 格子保留,不销毁——随面板 GameObject 一同隐藏
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
// 面板真正销毁时才清理格子
|
||||
foreach (var cell in _cells.Values)
|
||||
if (cell != null) Destroy(cell.gameObject);
|
||||
_cells.Clear();
|
||||
}
|
||||
|
||||
// 面板重新打开时同步关闭期间积累的探索进度
|
||||
private void RefreshAllCells()
|
||||
{
|
||||
var mapManager = ServiceLocator.GetOrDefault<IMapService>();
|
||||
foreach (var (roomId, cell) in _cells)
|
||||
{
|
||||
if (cell == null) continue;
|
||||
bool discovered = mapManager != null && mapManager.IsExplored(roomId);
|
||||
cell.SetDiscovered(discovered);
|
||||
}
|
||||
}
|
||||
|
||||
// ── 内部 ──────────────────────────────────────────────────────────────
|
||||
|
||||
private void BuildGrid()
|
||||
{
|
||||
if (_database == null || _database.AllRooms == null) return;
|
||||
|
||||
var mapManager = ServiceLocator.GetOrDefault<IMapService>();
|
||||
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 ─────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>地图面板中每个房间对应的格子 UI 组件。</summary>
|
||||
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;
|
||||
|
||||
/// <summary>初始化格子(位置、颜色、图标)。</summary>
|
||||
public void Setup(MapRoomDataSO room, bool discovered, Sprite icon)
|
||||
{
|
||||
// 根据 GridPosition/GridSize 设置 RectTransform 位置与大小
|
||||
if (TryGetComponent<RectTransform>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user