105 lines
3.7 KiB
C#
105 lines
3.7 KiB
C#
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;
|
||
}
|
||
}
|