> For the complete documentation index, see [llms.txt](https://docs.convai.com/api-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/narrative-design/setting-up-narrative-design-triggers.md).

# 配置叙事设计触发器

`ConvaiNarrativeDesignTrigger` 向 Convai 发送一个命名信号，用于将故事图从一个部分推进到下一个部分。将它放在任何 GameObject 上——门口、展品、UI 按钮的事件目标——并选择它应如何激活。叙事触发器不同于 Unity Physics 触发器：激活模式控制 *当* 信号何时发送，而不是触发哪种 Unity 物理事件。

### 添加触发器组件

{% stepper %}
{% step %}

#### 创建或选择一个 GameObject

对于基于区域的激活（Collision、Proximity、TimeBased），请创建一个空的 GameObject，并将其放置在你希望触发区域出现的场景位置。对于手动激活，你可以将该组件放在任何地方。
{% endstep %}

{% step %}

#### 添加组件

点击 **添加组件** 并导航到 **Convai > Convai 叙事设计触发器**.

<figure><img src="/files/f31afed5e6e2c20cf7368631c1da21a21b48c430" alt="ConvaiNarrativeDesignTrigger added via Add Component in the Unity Inspector"><figcaption><p>将 ConvaiNarrativeDesignTrigger 添加到一个 GameObject。</p></figcaption></figure>
{% endstep %}

{% step %}

#### 分配角色

拖动你的 `ConvaiCharacter` 到 **角色** 字段中。如果留空， **自动查找角色** 会先搜索父级层级，然后自动搜索 `ConvaiManager`的角色列表。如果场景中有多个角色，请明确指定目标。
{% endstep %}

{% step %}

#### 获取并选择一个触发器

点击 **获取** 在 **触发器选择** 部分。SDK 调用 `NarrativeDesignFetcher.FetchTriggersAsync` 并将仪表板上为该角色定义的所有触发器填充到下拉菜单中。

选择你希望此组件发送的触发器。以下字段会自动填充： **触发器名称**, **触发器 ID**，以及 **目标章节** 字段。

<figure><img src="/files/fd46e8f0697313cf3efb9fcd2a656be7b996b08c" alt="Trigger Selection dropdown showing fetched triggers from the Convai dashboard"><figcaption><p>来自 Convai 仪表板填充的触发器下拉菜单。</p></figcaption></figure>
{% endstep %}

{% step %}

#### 选择一种激活模式

选择下面描述的四种激活模式之一，并配置其设置。
{% endstep %}
{% endstepper %}

### 激活模式

<figure><img src="/files/d99c5bb210f9452811502883c6df79cbaa5e9d96" alt="Activation Settings header in the Inspector showing all four activation mode options"><figcaption><p>带有模式选择器的激活设置标题。</p></figcaption></figure>

#### 碰撞

默认模式。当带有指定标签的玩家 GameObject 进入附加在同一 GameObject 上的碰撞体时，触发器会触发。

**要求：**

* 一个 `Collider` 组件，且位于同一个 GameObject 上，并启用 **Is Trigger** 。
* 触发器 GameObject 或玩家 GameObject 其中之一必须具有 `Rigidbody` ，Unity 物理系统才能生成 `OnTriggerEnter` 回调。

{% hint style="warning" %}
如果 **Is Trigger** 未在碰撞体上启用，或者触发器对象和玩家都没有 `Rigidbody`, `OnTriggerEnter` 则永远不会触发。启用 **启动时验证** 以便在场景运行时自动捕获此问题。
{% endhint %}

**检测设置：**

| 字段       | 默认值    | 描述                            |
| -------- | ------ | ----------------------------- |
| **玩家标签** | `"玩家"` | 只有带有此标签的 GameObject 才会被识别为玩家。 |
| **玩家层**  | 所有层    | 用于进一步筛选哪些对象算作玩家的层遮罩。          |

#### 接近

当玩家与组件的 `Transform` 之间的距离落入 **接近半径**内时，触发器会触发。检查会在 `Update`中的每一帧运行。场景视图中会绘制一个绿色球体，显示检测半径。

| 字段         | 默认值    | 描述                                           |
| ---------- | ------ | -------------------------------------------- |
| **接近半径**   | `3`    | 以世界单位表示的检测半径。                                |
| **玩家标签**   | `"玩家"` | 用于标识玩家的标签。                                   |
| **自动查找玩家** | `true` | 如果未分配玩家 GameObject，则在场景中搜索带标签的玩家 GameObject。 |

此模式不需要碰撞体。

#### 基于时间

当玩家在碰撞体区域内停留达到设定时长后，触发器会触发。如果玩家在延迟结束前离开，倒计时会取消，并在玩家下次进入时重新开始。

**要求：** 与 Collision 模式相同的碰撞体设置。

| 字段       | 默认值    | 描述                     |
| -------- | ------ | ---------------------- |
| **时间延迟** | `0`    | 玩家必须在区域内停留多少秒后触发器才会触发。 |
| **玩家标签** | `"玩家"` | 用于标识玩家的标签。             |

#### 手动

触发器不会自动执行任何操作。调用 `InvokeTrigger()` 或 `TryInvokeTrigger()` ，即可从你自己的代码或 Unity Event 中触发它。当激活条件完全由你的游戏逻辑控制时，请使用此模式——例如 UI 按钮、任务完成回调或计分交互。

```csharp
// 从代码触发触发器
narrativeTrigger.InvokeTrigger();

// 静默尝试——如果 TriggerOnce 已经触发，则跳过且不警告
narrativeTrigger.TryInvokeTrigger();
```

### 自动恢复设置

这些设置使触发器能够适应常见的运行时情况，即角色或玩家可能不会立即就绪。

<figure><img src="/files/2a8bc86fdb1854eb011504061345e4d00029aa95" alt="Auto-Recovery Settings header in the Inspector"><figcaption><p>自动恢复设置标题。</p></figcaption></figure>

| 字段           | 默认值    | 描述                                                                                                                   |
| ------------ | ------ | -------------------------------------------------------------------------------------------------------------------- |
| **自动查找角色**   | `true` | 先搜索父级层级，然后搜索 `ConvaiManager.Characters`。如果只有一个角色则自动分配；如果找到多个角色，则记录警告。                                                |
| **自动查找玩家**   | `true` | 先按 Player Tag 搜索，然后按常见名称列表搜索，最后通过 `Camera.main.parent`.                                                              |
| **等待就绪前排队**  | `true` | 如果角色尚未处于活动对话中（`IsInConversation` 为 `false`），则触发器会进入队列，并在连接建立后自动触发。你无需 `IsInConversation` 在调用前手动检查 `InvokeTrigger()`. |
| **最大等待时间**   | `30`   | 等待角色就绪的最长秒数。设置为 `0` 表示无超时。                                                                                           |
| **在场景加载时重置** | `true` | 调用 `ResetTrigger()` ，每当场景加载时调用，因此在重新加载的场景中触发器可以再次触发。                                                                 |

{% hint style="warning" %}
设置 **最大等待时间** 到 `0` 在会话可能永远无法连接的正式构建中进行此设置会创建一个无限期协程。除非你明确控制会话生命周期，否则务必设置合理的超时时间。
{% endhint %}

### 控制触发频率

**仅触发一次** （默认 `true`）可防止触发器多次触发。首次成功调用后， `HasTriggered` 变为 `true`, `CurrentStatus` 变为 `AlreadyFired`，之后所有调用都返回 `false`.

要让触发器再次触发，请调用 `ResetTrigger()`:

```csharp
narrativeTrigger.ResetTrigger();
```

`ResetTrigger()` 还会取消任何正在等待角色就绪的排队触发。

要让触发器在每次激活时都触发，请禁用 **仅触发一次** 在检查器中。

### 事件参考

| 事件                   | 签名                   | 触发时机                     |
| -------------------- | -------------------- | ------------------------ |
| `OnTriggerActivated` | `UnityEvent`         | 触发器已成功发送到后端。             |
| `OnPlayerEnterZone`  | `UnityEvent`         | 玩家进入了碰撞体或接近区域（在触发器触发之前）。 |
| `OnPlayerExitZone`   | `UnityEvent`         | 玩家离开了碰撞体或接近区域。           |
| `OnTriggerFailed`    | `UnityEvent<string>` | 触发器无法触发。字符串参数包含错误消息。     |
| `OnTriggerQueued`    | `UnityEvent`         | 触发器已被接受，但因角色尚未进入对话而延后。   |

### 触发器状态

该 `CurrentStatus` 属性会始终跟踪触发器的状态：

```mermaid
stateDiagram-v2
    [*] --> Ready
    Ready --> AlreadyFired : InvokeTrigger() 成功\n(TriggerOnce = true)
    Ready --> QueuedWaitingForCharacter : 调用 InvokeTrigger()\n角色未就绪\nQueueUntilReady = true
    Ready --> ConfigurationError : ValidateConfiguration() 失败
    QueuedWaitingForCharacter --> AlreadyFired : 角色已就绪
    QueuedWaitingForCharacter --> ConfigurationError : 超过 MaxWaitTime
    AlreadyFired --> Ready : ResetTrigger()
    ConfigurationError --> Ready : 修复问题 + ResetTrigger()
    Ready --> Disabled : 组件或 GameObject 被禁用
    Disabled --> Ready : 组件或 GameObject 重新启用
```

参见 [排查叙事设计问题](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/narrative-design/troubleshooting-and-diagnostics.md) ，获取每种状态的完整解决指南。

### 检查器参考

#### 角色引用标题

| 字段         | 默认值    | 描述                                                |
| ---------- | ------ | ------------------------------------------------- |
| **角色**     | 无      | 目标 `ConvaiCharacter`。如果留空并且 **自动查找角色** 已启用，则自动查找。 |
| **自动查找角色** | `true` | 如果 Character 字段为空，则搜索层级和 ConvaiManager。           |

#### 触发器选择标题

| 字段         | 默认值 | 描述                                            |
| ---------- | --- | --------------------------------------------- |
| **触发器 ID** | 空   | 选择后只读。来自仪表板的唯一标识符。                            |
| **触发器名称**  | 空   | 所选触发器的显示名称。                                   |
| **触发消息**   | 空   | 随触发器发送的可选消息载荷。可通过程序设置为 `SetTriggerMessage()`. |

#### 激活设置标题

| 字段        | 默认值    | 描述                                    |
| --------- | ------ | ------------------------------------- |
| **激活模式**  | `碰撞`   | 触发器如何激活： `碰撞`, `接近`, `手动`，或 `基于时间`.   |
| **接近半径**  | `3`    | Proximity 模式的检测半径。                    |
| **时间延迟**  | `0`    | TimeBased 模式的倒计时秒数。                   |
| **仅触发一次** | `true` | 如果启用，则仅触发一次，直到 `ResetTrigger()` 被调用时。 |
| **玩家层**   | 全部     | 用于玩家检测的层遮罩。                           |
| **玩家标签**  | `"玩家"` | 用于标识玩家 GameObject 的标签。                |

#### 自动恢复设置标题

| 字段           | 默认值    | 描述                        |
| ------------ | ------ | ------------------------- |
| **自动查找玩家**   | `true` | 如果未检测到玩家，则在场景中搜索带标签的玩家。   |
| **等待就绪前排队**  | `true` | 将触发器延后，直到角色会话打开。          |
| **最大等待时间**   | `30`   | 队列超时时间（秒）。 `0` = 无超时。     |
| **在场景加载时重置** | `true` | 重置 `HasTriggered` 于场景加载时。 |

#### 诊断标题

| 字段        | 默认值     | 描述                                               |
| --------- | ------- | ------------------------------------------------ |
| **启用诊断**  | `false` | 将详细状态转换记录到控制台。                                   |
| **启动时验证** | `true`  | 运行 `ValidateConfiguration()` 在 Start 时执行并记录任何问题。 |

### 下一步

{% content-ref url="/pages/630c1743293b81e62f2237b571dcf928c0d73285" %}
[配置叙事模板键](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/narrative-design/template-keys-dynamic-narrative-variables.md)
{% endcontent-ref %}

{% content-ref url="/pages/e2aeb655628e9664d3a8c2993eb219a88fcfeef0" %}
[叙事设计脚本参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/narrative-design/scripting-narrative-design.md)
{% endcontent-ref %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/narrative-design/setting-up-narrative-design-triggers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
