- Round 8 report highlights improvements in architecture, editor usability, and data robustness, with a total score of 80/100. - Round 9 report focuses on editor extension capabilities, identifying issues with room data indexing and layout editing, resulting in a score of 76/100. - Round 26 report evaluates the system against commercial standards, noting new issues and confirming previous fixes, with a score of 95.8/100.
143 lines
6.0 KiB
C#
143 lines
6.0 KiB
C#
using System;
|
||
using System.Collections;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using UnityEngine.EventSystems;
|
||
|
||
namespace BaseGames.World.Map
|
||
{
|
||
/// <summary>房间可见性三级状态:未知 / 已踏入 / 已标注(购买地图碎片)。</summary>
|
||
public enum RoomVisibility { Unknown, Explored, Mapped }
|
||
|
||
/// <summary>
|
||
/// 地图面板中每个房间对应的格子 UI 组件(架构 15_MapShopModule §1.3)。
|
||
/// <para>同时被 MapPanel(全屏地图)和 MinimapHUD(角落小地图)复用。</para>
|
||
/// 颜色通过 <see cref="SetColors"/> 从外部注入,不在此处硬编码。
|
||
/// <para><see cref="RT"/> 属性在 Awake 中缓存,避免调用方反复 GetComponent。</para>
|
||
/// </summary>
|
||
public class MapRoomCellUI : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
|
||
{
|
||
[SerializeField] private Image _bg;
|
||
[SerializeField] private Image _icon;
|
||
[SerializeField] private RawImage _outlineImage; // 可选:房间非矩形轮廓纹理
|
||
[SerializeField] private Image _highlight; // 可选:当前房间高亮描边(玩家所在时激活)
|
||
[SerializeField] private Image _fogOverlay; // 可选:未知房间雾效覆盖层(R12-FD)
|
||
|
||
// 实例颜色(默认值与原硬编码保持一致);可通过 SetColors 统一覆盖
|
||
private Color _colExplored = Color.white;
|
||
private Color _colMapped = new Color(0.45f, 0.45f, 0.45f, 1f);
|
||
private Color _colUnknown = Color.black;
|
||
private RoomVisibility _currentVisibility;
|
||
|
||
private string _displayName;
|
||
private Action<string> _onHover;
|
||
private Action _onHoverExit;
|
||
|
||
/// <summary>格子的 RectTransform(Awake 中缓存,外部直接访问无需 GetComponent)。</summary>
|
||
public RectTransform RT { get; private set; }
|
||
|
||
private void Awake() => RT = GetComponent<RectTransform>();
|
||
|
||
/// <summary>
|
||
/// 初始化格子(可见性、图标、Tooltip 回调)。
|
||
/// <para>R11-N8:不再在 Setup 中设置位置/尺寸,调用方按需调用
|
||
/// <see cref="SetGridLayout"/> 或直接操作 <see cref="RT"/>。</para>
|
||
/// </summary>
|
||
public void Setup(MapRoomDataSO room, RoomVisibility visibility, Sprite icon,
|
||
Action<string> onHover = null, Action onHoverExit = null)
|
||
{
|
||
_displayName = room.DisplayName;
|
||
_onHover = onHover;
|
||
_onHoverExit = onHoverExit;
|
||
|
||
// 房间轮廓纹理(非矩形形状,覆盖在矩形背景上方)
|
||
if (_outlineImage != null)
|
||
{
|
||
_outlineImage.texture = room.RoomOutlineTex;
|
||
_outlineImage.enabled = room.RoomOutlineTex != null;
|
||
}
|
||
|
||
SetVisibility(visibility);
|
||
|
||
if (_icon != null)
|
||
{
|
||
_icon.sprite = icon;
|
||
_icon.enabled = icon != null;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// R11-N8 独立布局接口:根据房间格子坐标与单格像素数设定位置和尺寸。
|
||
/// <para>MapPanel.BuildGrid 与 MinimapHUD.PlaceCell 均通过此接口定位,
|
||
/// 两者互不干扰,消除 Setup 中的重复赋值。</para>
|
||
/// </summary>
|
||
public void SetGridLayout(MapRoomDataSO room, float pixelsPerCell)
|
||
{
|
||
RT.anchoredPosition = new Vector2(room.GridPosition.x * pixelsPerCell,
|
||
room.GridPosition.y * pixelsPerCell);
|
||
RT.sizeDelta = new Vector2(room.GridSize.x * pixelsPerCell,
|
||
room.GridSize.y * pixelsPerCell);
|
||
}
|
||
|
||
/// <summary>覆盖此格子的三级可见性颜色(通常由 MapPanel / MinimapHUD 在创建后统一调用)。</summary>
|
||
public void SetColors(Color explored, Color mapped, Color unknown)
|
||
{
|
||
_colExplored = explored;
|
||
_colMapped = mapped;
|
||
_colUnknown = unknown;
|
||
SetVisibility(_currentVisibility); // 用新颜色重新渲染当前状态
|
||
}
|
||
|
||
public void SetVisibility(RoomVisibility v)
|
||
{
|
||
_currentVisibility = v;
|
||
if (_bg == null) return;
|
||
_bg.color = v switch
|
||
{
|
||
RoomVisibility.Explored => _colExplored,
|
||
RoomVisibility.Mapped => _colMapped,
|
||
_ => _colUnknown,
|
||
};
|
||
// R12-FD 雾效覆盖层:仅在完全未知时显示
|
||
if (_fogOverlay != null)
|
||
_fogOverlay.enabled = v == RoomVisibility.Unknown;
|
||
}
|
||
|
||
/// <summary>向后兼容:直接传 bool 时等同于 Explored / Unknown。</summary>
|
||
public void SetDiscovered(bool v)
|
||
=> SetVisibility(v ? RoomVisibility.Explored : RoomVisibility.Unknown);
|
||
|
||
/// <summary>激活/取消当前房间高亮描边。</summary>
|
||
public void SetHighlight(bool v)
|
||
{
|
||
if (_highlight != null) _highlight.enabled = v;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 新发现房间时播放闪白淡出动画(R12-FC)。
|
||
/// 由 MapPanel.OnRoomMappedAnim 调用;协程安全:组件被销毁后 Unity 自动终止。
|
||
/// </summary>
|
||
public IEnumerator PlayRevealAnim(Color flashColor, float duration)
|
||
{
|
||
if (_bg == null) yield break;
|
||
var original = _bg.color;
|
||
_bg.color = flashColor;
|
||
float elapsed = 0f;
|
||
while (elapsed < duration)
|
||
{
|
||
_bg.color = Color.Lerp(flashColor, original, elapsed / duration);
|
||
elapsed += Time.unscaledDeltaTime;
|
||
yield return null;
|
||
}
|
||
_bg.color = original;
|
||
}
|
||
|
||
public void OnPointerEnter(PointerEventData _)
|
||
{
|
||
if (!string.IsNullOrEmpty(_displayName)) _onHover?.Invoke(_displayName);
|
||
}
|
||
|
||
public void OnPointerExit(PointerEventData _) => _onHoverExit?.Invoke();
|
||
}
|
||
}
|