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; } }