摄像机区域的架构改动
This commit is contained in:
86
Assets/_Game/Scripts/Tutorial/TutorialManager.cs
Normal file
86
Assets/_Game/Scripts/Tutorial/TutorialManager.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user