角色能力,存档
This commit is contained in:
104
Assets/_Game/Scripts/World/Map/RegionNameDisplay.cs
Normal file
104
Assets/_Game/Scripts/World/Map/RegionNameDisplay.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user