124 lines
4.5 KiB
Markdown
124 lines
4.5 KiB
Markdown
# ShrinkTutorial
|
||
|
||
一个面向 Unity 2022.3+ 的互动式引导系统,重点解决这几件事:
|
||
|
||
共享教程状态与步骤运行时位于 `DotNet~`;Godot 4.6 的 `Resource`、`Control` 遮罩和输入适配位于 `Godot~`。Godot 项目安装 `ShrinkSDK.Tutorial.Godot`。
|
||
|
||
- 通过真实点击完成步骤,而不是纯文案翻页。
|
||
- 支持静态路径目标和动态锚点目标。
|
||
- 遮罩只屏蔽无关区域,目标区域可继续点击。
|
||
- 教程内容由 `ScriptableObject` 驱动,运行时由 `ShrinkTutorialManager` 调度。
|
||
|
||
## 当前能力
|
||
|
||
| 能力 | 说明 |
|
||
|------|------|
|
||
| 数据驱动教程 | `ShrinkTutorialData + ShrinkTutorialStep + ShrinkTutorialDatabase` |
|
||
| 运行时调度 | `ShrinkTutorialManager` 负责排队、前置检查、逐步执行、完成/跳过持久化 |
|
||
| 目标定位 | 支持 `Hierarchy Path` 与 `AnchorId` |
|
||
| 完成条件 | `ClickTarget / AnyClick / CustomEvent / Auto` |
|
||
| 动态目标等待 | `waitForTarget + waitTimeout` |
|
||
| 默认 UI | 独立 Overlay Canvas、遮罩挖洞、提示框、箭头、跳过按钮 |
|
||
| 编辑器入口 | `ShrinkSDK/引导/教程编辑器`、`ShrinkSDK/引导/重置教程进度` |
|
||
|
||
## 暂未覆盖
|
||
|
||
- `DragToTarget` 目前按自定义事件完成处理,尚未内建拖拽命中判定。
|
||
- 圆形高亮当前以圆形点击判定为主,视觉挖洞仍按外接矩形处理。
|
||
- 本地化只提供接口 `IShrinkTutorialLocalizationProvider`,不内置具体表系统。
|
||
|
||
## 目录结构
|
||
|
||
```text
|
||
Assets/Modules/ShrinkTutorial/
|
||
├── Runtime/
|
||
│ ├── Core/
|
||
│ ├── Storage/
|
||
│ ├── Trigger/
|
||
│ └── UI/
|
||
└── Editor/
|
||
```
|
||
|
||
## 快速接入
|
||
|
||
### 1. 创建配置资产
|
||
|
||
通过菜单创建:
|
||
|
||
- `Assets -> Create -> ShrinkTutorial -> Settings`
|
||
- `Assets -> Create -> ShrinkTutorial -> Tutorial Database`
|
||
- `Assets -> Create -> ShrinkTutorial -> Tutorial Data`
|
||
|
||
然后把教程资产挂到 `ShrinkTutorialDatabase`,再把数据库挂到 `ShrinkTutorialSettings.database`。
|
||
|
||
### 2. 配置步骤
|
||
|
||
常见配置建议:
|
||
|
||
- `targetMode = Path`:用于静态 UI / 场景对象。
|
||
- `targetMode = AnchorId`:用于运行时实例化对象。
|
||
- `completeCondition = ClickTarget`:最常用的真实点击引导。
|
||
对 UI 目标会在指针释放且 EventSystem 射线真实命中目标后再过步,避免遮罩或浮层导致“业务没执行但教程已前进”。
|
||
- `completeCondition = CustomEvent`:业务代码在成功后调用 `CompleteStep(...)`。
|
||
|
||
### 3. 触发教程
|
||
|
||
可以直接调用:
|
||
|
||
```csharp
|
||
ShrinkTutorialManager.Instance.StartTutorial("tut.inventory.open");
|
||
```
|
||
|
||
如果项目要求所有 UI 预先存在于场景,可在 `ShrinkTutorialManager` 上显式绑定
|
||
`Canvas Override`、`Mask Override` 与 `Dialog Override`,并关闭
|
||
`Allow Runtime Ui Fallback`。`ShrinkTutorialDialog` 的内容文本、箭头与跳过按钮也要
|
||
在场景中序列化绑定;该模式不会在运行时创建教程 UI。
|
||
|
||
也可以给入口物体挂 `ShrinkTutorialTrigger`,在 `OnEnable` 首次可见时自动触发。
|
||
|
||
### 4. 动态对象锚点
|
||
|
||
给动态实例化对象挂 `ShrinkTutorialAnchor`,填写 `anchorId`,步骤里选择 `AnchorId` 模式即可。
|
||
|
||
## 外部接口
|
||
|
||
```csharp
|
||
ShrinkTutorialManager.Instance.StartTutorial("tutorial.id");
|
||
ShrinkTutorialManager.Instance.CompleteStep("event_name");
|
||
ShrinkTutorialManager.Instance.SkipCurrent();
|
||
ShrinkTutorialManager.Instance.PauseCurrent();
|
||
ShrinkTutorialManager.Instance.ResumeCurrent();
|
||
```
|
||
|
||
状态查询:
|
||
|
||
```csharp
|
||
var done = ShrinkTutorialManager.Instance.HasCompleted("tutorial.id");
|
||
var skipped = ShrinkTutorialManager.Instance.HasSkipped("tutorial.id");
|
||
var running = ShrinkTutorialManager.Instance.IsRunning;
|
||
```
|
||
|
||
## 本地化接入
|
||
|
||
如果项目已有本地化系统,实现下面接口后注入即可:
|
||
|
||
```csharp
|
||
public sealed class MyTutorialLocalizer : IShrinkTutorialLocalizationProvider
|
||
{
|
||
public bool TryResolve(string key, out string text)
|
||
{
|
||
text = MyLocalization.Get(key);
|
||
return !string.IsNullOrWhiteSpace(text);
|
||
}
|
||
}
|
||
|
||
ShrinkTutorialLocalization.Provider = new MyTutorialLocalizer();
|
||
```
|
||
|
||
## 调试建议
|
||
|
||
- 先确认 `ShrinkTutorialSettings.database` 已正确赋值。
|
||
- 如果目标是动态对象,优先检查 `ShrinkTutorialAnchorRegistry` 是否已注册该 `anchorId`。
|
||
- 如果步骤目标当前还没显示出来,不要把它视为异常;`Path` 目标在 `activeInHierarchy == false` 时现在会继续等待,而不是提前显示到隐藏控件上。
|
||
- 如果步骤走 `CustomEvent`,确认业务代码在真正完成后再调用 `CompleteStep(...)`。
|