Files
zeling_v2/Assets/_Game/Scripts/World/Map/RegionNameDisplay.cs
2026-05-19 11:50:21 +08:00

105 lines
3.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections;
using UnityEngine;
using TMPro;
using BaseGames.Core;
using BaseGames.Core.Events;
namespace BaseGames.World.Map
{
/// <summary>
/// 进入新区域时在屏幕中央短暂渐显区域名称(架构 15_MapShopModule §1.6)。
/// 挂在 HUD 根节点下,订阅 EVT_RegionChanged执行淡入—保持—淡出动画序列。
/// 可通过 _regionNames 配置原始 RegionId 到本地化显示名的映射;未配置时直接显示 RegionId。
/// </summary>
[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<CanvasGroup>();
_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;
}
}