using System;
using System.Collections;
using UnityEngine;
using TMPro;
using BaseGames.Core;
using BaseGames.Core.Events;
namespace BaseGames.World.Map
{
///
/// 进入新区域时在屏幕中央短暂渐显区域名称(架构 15_MapShopModule §1.6)。
/// 挂在 HUD 根节点下,订阅 EVT_RegionChanged,执行淡入—保持—淡出动画序列。
/// 可通过 _regionNames 配置原始 RegionId 到本地化显示名的映射;未配置时直接显示 RegionId。
///
[RequireComponent(typeof(CanvasGroup))]
public class RegionNameDisplay : MonoBehaviour
{
[SerializeField] private TMP_Text _regionText;
[Header("动画时长(秒)")]
[SerializeField] [Range(0.1f, 2f)] private float _fadeDuration = 0.4f;
[SerializeField] [Range(0.5f, 5f)] private float _holdDuration = 2.0f;
[Header("区域名映射(留空则直接显示 RegionId)")]
[SerializeField] private RegionNameEntry[] _regionNames;
[Header("Event Channels")]
[SerializeField] private StringEventChannelSO _onRegionChanged;
private CanvasGroup _cg;
private Coroutine _showCoroutine;
private readonly CompositeDisposable _subs = new();
private void Awake()
{
_cg = GetComponent();
_cg.alpha = 0f;
gameObject.SetActive(false);
}
private void OnEnable()
{
_onRegionChanged?.Subscribe(OnRegionChanged).AddTo(_subs);
}
private void OnDisable()
{
_subs.Clear();
}
// ── 事件响应 ──────────────────────────────────────────────────────────
private void OnRegionChanged(string regionId)
{
if (string.IsNullOrEmpty(regionId)) return;
if (_regionText != null)
_regionText.text = ResolveDisplayName(regionId);
if (_showCoroutine != null) StopCoroutine(_showCoroutine);
_showCoroutine = StartCoroutine(ShowSequence());
}
// ── 动画序列 ──────────────────────────────────────────────────────────
private IEnumerator ShowSequence()
{
gameObject.SetActive(true);
yield return StartCoroutine(FadeTo(1f));
yield return new WaitForSecondsRealtime(_holdDuration);
yield return StartCoroutine(FadeTo(0f));
gameObject.SetActive(false);
}
private IEnumerator FadeTo(float target)
{
float start = _cg.alpha;
float elapsed = 0f;
while (elapsed < _fadeDuration)
{
_cg.alpha = Mathf.Lerp(start, target, elapsed / _fadeDuration);
elapsed += Time.unscaledDeltaTime;
yield return null;
}
_cg.alpha = target;
}
// ── 辅助方法 ──────────────────────────────────────────────────────────
private string ResolveDisplayName(string regionId)
{
if (_regionNames != null)
foreach (var e in _regionNames)
if (e.RegionId == regionId) return e.DisplayName;
return regionId;
}
}
[Serializable]
public struct RegionNameEntry
{
public string RegionId;
public string DisplayName;
}
}