Files
zeling_v2/Assets/Scripts/Tutorial/TutorialManager.cs
2026-05-13 09:19:54 +08:00

87 lines
3.6 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.Collections;
using System.Collections.Generic;
using UnityEngine;
using BaseGames.Core.Save;
namespace BaseGames.Tutorial
{
/// <summary>
/// 教程提示管理器(架构 21_LiquidPuzzleModule §17
/// 通过 ServiceLocator 注册,实现 ISaveable 将已完成提示 ID 持久化。
/// ShowHint若 ID 已完成则跳过;否则显示,并在 duration 秒后自动隐藏。
/// CompleteHint标记为已完成写回 SaveData。
/// </summary>
public class TutorialManager : MonoBehaviour, ISaveable, ITutorialService
{
[SerializeField] private TutorialHintUI _hintUI;
private readonly HashSet<string> _completedHints = new();
// ── Unity 生命周期 ────────────────────────────────────
private void Awake()
{
if (BaseGames.Core.ServiceLocator.GetOrDefault<ITutorialService>() != null) { Destroy(gameObject); return; }
BaseGames.Core.ServiceLocator.Register<ITutorialService>(this);
// 生命周期由 Persistent 场景根 GameObject 统一管理,不在此调用 DontDestroyOnLoad
}
private void OnDestroy()
{
BaseGames.Core.ServiceLocator.Unregister<ITutorialService>(this);
}
private void OnEnable()
{
BaseGames.Core.ServiceLocator.GetOrDefault<BaseGames.Core.Save.ISaveableRegistry>()?.Register(this);
}
private void OnDisable()
{
BaseGames.Core.ServiceLocator.GetOrDefault<BaseGames.Core.Save.ISaveableRegistry>()?.Unregister(this);
}
// ── 公共 API ──────────────────────────────────────────────────────
/// <summary>
/// 显示提示。若 hintId 已完成则忽略。
/// <paramref name="hintId"/>: 唯一提示 ID可作为去重键和保存键
/// <paramref name="text"/>: 本地化后的显示文字。
/// <paramref name="duration"/>: 自动消隐秒数(≤ 0 则不自动消隐)。
/// </summary>
public void ShowHint(string hintId, string text, float duration = 4f)
{
if (_completedHints.Contains(hintId)) return;
if (_hintUI == null) return;
_hintUI.Show(text, duration);
}
/// <summary>标记提示为已完成,并自动隐藏当前显示中的提示。</summary>
public void CompleteHint(string hintId)
{
if (_completedHints.Add(hintId))
{
_hintUI?.Hide();
// 持久化由 ISaveable.OnSave 统一处理,此处仅更新内存状态
}
}
/// <summary>查询指定提示是否已完成。</summary>
public bool IsHintCompleted(string hintId) => _completedHints.Contains(hintId);
// ── ISaveable ─────────────────────────────────────────────────────
public void OnSave(SaveData data)
{
if (data?.Tutorial == null) return;
data.Tutorial.CompletedHintIds.Clear();
data.Tutorial.CompletedHintIds.AddRange(_completedHints);
}
public void OnLoad(SaveData data)
{
_completedHints.Clear();
if (data?.Tutorial == null) return;
foreach (var id in data.Tutorial.CompletedHintIds)
_completedHints.Add(id);
}
}
}