> 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/character-actions/usage-examples.md).

# 角色动作示例

Convai 角色动作系统的渐进式示例——Inspector 设置、事件订阅、脚本化批量注入以及观察动作。

这六个示例从最简单的可能配置逐步推进到完整的脚本控制。每个示例都是独立的——你可以不先阅读其他示例，直接跟着其中任意一个学习。

### 示例 1 — 消防安全取物（检查器设置，无代码）

**场景：** 一个消防安全培训模拟。学员提出请求时，讲师 NPC 会取来灭火器。无需脚本。

**先决条件：** 场景中已烘焙 NavMesh。

#### 检查器配置

在讲师 NPC 的 `游戏对象`上，添加以下组件：

* `ConvaiCharacter`
* `ConvaiActionConfigSource`
* `ConvaiActionDispatcher` （保持这两个策略为默认值：Queue、StopBatch）
* `ConvaiWalkToActionExecutor` — `_arriveDistance = 0.6`
* `ConvaiPointAtActionExecutor` ——保持 `保持秒数` 于 `3`。它通过 `ConvaiBodyAnimationController`驱动手臂，因此角色也需要该组件。

在 `ConvaiActionConfigSource`:

**动作定义：**

| 动作名称       | 目标要求   | 执行器                           |
| ---------- | ------ | ----------------------------- |
| `Retrieve` | `对象`   | `ConvaiWalkToActionExecutor`  |
| `指向`       | `二者之一` | `ConvaiPointAtActionExecutor` |

**可操作对象：**

| 名称             | 说明                         |
| -------------- | -------------------------- |
| `Extinguisher` | 主泵控制面板旁墙上支架中的红色便携式 CO2 灭火器 |
| `Alarm Panel`  | 安装在场地入口附近的带红色拉柄的紧急报警面板     |

**预期结果：**

* “取来灭火器”→ NPC 走到灭火器旁，并在距离 0.6 个单位处停下。
* “指向报警面板”→ NPC 朝报警面板抬起一只手臂，保持指向 3 秒，然后放下手臂。
* “取来报警”→ Convai 会根据描述正确将“alarm”解析为“Alarm Panel”。

{% hint style="success" %}
打开 Console 并按以下内容筛选 `ConvaiActionDebugProbe` （如果添加了探针）。你应该会看到：

```
[ConvaiActionDebugProbe] Step succeeded #1: cmd='Retrieve Extinguisher', def='Retrieve', target=Object:Extinguisher
```

{% endhint %}

### 示例 2 — 入职检查清单集成（事件订阅）

**场景：** 一个企业入职培训模拟。当 NPC 演示每个工作站时，检查清单 UI 会前进。完成完整的设备参观后，培训阶段会推进。

#### C# 设置

将 `OnBatchCompleted` 到检查清单管理器。如果你在检查器中进行连接，则转发器一侧不需要额外代码。对于代码驱动的连接：

```csharp
using Convai.Runtime.Actions;
using UnityEngine;

public sealed class OnboardingTourController : MonoBehaviour
{
    [SerializeField] private ConvaiActionDispatcher _dispatcher;
    [SerializeField] private TrainingChecklistUI _checklist;

    private void OnEnable()
    {
        _dispatcher.OnBatchCompleted.AddListener(HandleTourStepCompleted);
        _dispatcher.OnBatchAborted.AddListener(HandleTourStepFailed);
    }

    private void OnDisable()
    {
        _dispatcher.OnBatchCompleted.RemoveListener(HandleTourStepCompleted);
        _dispatcher.OnBatchAborted.RemoveListener(HandleTourStepFailed);
    }

    private void HandleTourStepCompleted()
    {
        _checklist.MarkCurrentStepComplete();
        _checklist.AdvanceToNextStep();
    }

    private void HandleTourStepFailed()
    {
        _checklist.MarkCurrentStepIncomplete();
    }
}
```

**ConvaiActionConfigSource 定义：**

| 动作名称          | 目标要求 | 执行器                          |
| ------------- | ---- | ---------------------------- |
| `走向`          | `对象` | `ConvaiWalkToActionExecutor` |
| `Demonstrate` | `对象` | `ConvaiLookAtActionExecutor` |

**可操作对象：** 每个工作站都注册了其名称和位置描述。

**预期结果：** 学员说“带我看看文件系统”。NPC 走到文件柜前，面向它，并 `OnBatchCompleted` 触发——检查清单会自动推进到下一步。

### 示例 3 — 带回退对话的导航失败（错误恢复）

**场景：** 一个施工现场安全模拟。当 NPC 无法到达危险区域（路径被阻挡）时，它会承认障碍，而不是静默停止。

#### C# 设置

订阅 `OnStepFailed` 并注入一个动态上下文事件，使 NPC 说出自然的回退内容：

```csharp
using Convai.Runtime.Actions;
using UnityEngine;

public sealed class ActionFailureHandler : MonoBehaviour
{
    [SerializeField] private ConvaiActionDispatcher _dispatcher;
    [SerializeField] private ConvaiCharacter _character;

    private void OnEnable() =>
        _dispatcher.OnStepFailed.AddListener(HandleStepFailed);

    private void OnDisable() =>
        _dispatcher.OnStepFailed.RemoveListener(HandleStepFailed);

    private void HandleStepFailed(ConvaiActionInvocation invocation)
    {
        if (invocation.Command.Name != "Move To") return;

        string targetName = string.IsNullOrEmpty(invocation.Command.Target)
            ? "那个位置"
            : invocation.Command.Target;

        // 告诉 Convai 发生了什么，这样 NPC 就能自然地回应
        _character.DynamicContext.AddEvent(
            $"移动到 '{targetName}' 失败——路径被阻挡了。" );
    }
}
```

**预期结果：** NPC 朝危险区域前进， `NavMeshAgent` 未能完成路径时，执行器返回 `Failed`以及 `OnStepFailed` 触发。回退事件被注入，NPC 会说类似“我无法到达化学品存放区——通道被脚手架挡住了。”的话。

设置 `FailurePolicy` 移动到 `StopBatch` （默认）这样同一批次中的后续步骤（例如“演示危险”）就不会在导航步骤失败时运行。

### 示例 4 — 脚本化演示序列（程序化注入）

**场景：** 一个医疗程序培训模拟。在培训脚本中的某个预定时刻（由时间轴事件触发），NPC 会自动完成一次设备演示，而无需等待学员提问。

#### C# 设置

使用 `ConvaiActionDispatcher.EnqueueActions` 从时间轴触发器或 UI 按钮注入一个多步骤序列：

```csharp
using System.Collections.Generic;
using Convai.Runtime.Actions;
using Convai.Shared.Types;
using UnityEngine;

public sealed class DemonstrationTrigger : MonoBehaviour
{
    [SerializeField] private ConvaiActionDispatcher _dispatcher;

    // 从 Unity Timeline 信号、UI 按钮或游戏事件调用此方法
    public void RunDefibrillatorDemo()
    {
        _dispatcher.EnqueueActions(new List<ConvaiActionCommand>
        {
            new ConvaiActionCommand("Move To", "Equipment Cart"),
            new ConvaiActionCommand("Pick Up", "Defibrillator"),
            new ConvaiActionCommand("Move To", "Patient Bed"),
            new ConvaiActionCommand("Point At", "Patient Bed")
        });
    }
}
```

将 `RunDefibrillatorDemo` 一个 `UnityEngine.Timeline` 信号、UI 按钮 `OnClick`，或场景中的任何其他触发器。

**预期结果：** 讲师 NPC 走到设备推车旁，拿起除颤器，走到病床旁，并指向它——全程无需学员说任何话。 `OnBatchCompleted` 在序列结束时触发，你可以用它来推进培训阶段。

{% hint style="info" %}
`BatchPolicy = Queue` 确保如果学员正在与一个活动动作批次对话，这个脚本化序列会有礼貌地等待。若要切换为 `BatchPolicy = ReplaceCurrent` ，则演示应当中断任何正在进行的动作。
{% endhint %}

### 示例 5 — 与语音同步的展品指示（语音门控）

**场景：** 一个博物馆导览模拟。当访客询问某个展品时，NPC 会先口头回答，然后指向它。指向手势必须等到角色的语音台词真正开始播放后才能启动，否则 NPC 看起来会在说话前就指向展品。

#### C# 设置

设置 `等待机器人发言` 和 `机器人发言后延迟秒数` 在入队之前，于命令上设置：

```csharp
using System.Collections.Generic;
using Convai.Runtime.Actions;
using Convai.Shared.Types;
using UnityEngine;

public sealed class ExhibitPointerTrigger : MonoBehaviour
{
    [SerializeField] private ConvaiActionDispatcher _dispatcher;

    // 在 NPC 本轮的口头回答已被派发后调用此方法
    public void PointAtExhibit(string exhibitName)
    {
        var pointAction = new ConvaiActionCommand("Point At", exhibitName)
        {
            WaitForBotSpeech = true,
            DelayAfterBotSpeechSeconds = 0.3f
        };

        _dispatcher.EnqueueActions(new List<ConvaiActionCommand> { pointAction });
    }
}
```

**预期结果：** `pointAction` 是一个全新批次的第一步，因此 `ConvaiActionDispatcher` 会在语音门控处将其保持，直到运行它。只要角色的 `OnSpeechStarted`, `OnSpeechStopped`，或 `OnTurnCompleted` 事件触发——以先发生者为准——门控就会释放，然后再等待在 `机器人发言后延迟秒数` 中设置的额外 0.3 秒，

然后才执行指向手势。 `_speechGateTimeoutSeconds` 字段也会释放该步骤（默认 2 秒，在检查器的 Dispatch 标题下显示为“Speech Gate Timeout Seconds”），因此静默回合不会使批次停滞。

### 示例 6 — 博物馆展品的距离检查（观察动作）

**场景：** 一个博物馆导览模拟。访客询问某个展品离多远，NPC 会给出距离，而不是执行动作。这种动作的形态与前五个示例不同：执行器的工作是组织出一个回答，而不是移动或做手势。

#### 检查器配置

在讲师 NPC 的 `游戏对象`上，添加 `ConvaiMeasureDistanceActionExecutor` (`Add Component > Convai > Actions > Measure Distance`）。它不需要同级组件——在未解析到目标时，它会改为测量到玩家的距离。

在 `ConvaiActionConfigSource`:

**动作定义：**

| 动作名称   | 目标要求   | 执行器                                   |
| ------ | ------ | ------------------------------------- |
| `测量距离` | `二者之一` | `ConvaiMeasureDistanceActionExecutor` |

保留执行器的 **Distance Bands** 字段为默认值（`Within Reach` `1.2`, `A Few Steps` `3.5`, `Across The Area` `9`），并保持 **Include Metres** 勾选，这样口头回答就会包含测得的数值。

在动作定义上，设置 **Answer Delivery** 移动到 `Tell The Player` ——SDK 推荐用于任何回答问题的动作，例如读取仪表、计数或测量距离。

**预期结果：**

* “恐龙骨架有多远？”→ 执行器解析目标，测量地面平面距离，并返回一个已回答的结果，例如 `恐龙骨架离这里有几步远。大约 2.8 米。` ——Convai 会把答案说回给访客。
* “我离这里多远？”→ 在没有解析到目标时，执行器会改为测量到玩家的距离，并回答 `你就在触手可及的范围内。大约 0.9 米。`

`ConvaiMeasureDistanceActionExecutor` 返回 `ConvaiActionExecutionResult.Answered(...)` 而不是 `Succeeded(...)`。已回答结果包含 Convai 允许说出的句子；除此之外，结果的其他内容不会进入角色对世界的模型。 `ConvaiCountTargetGroupActionExecutor` (`Convai/Actions/Count Target Group`）遵循相同模式，用于计算一个的可用成员数量 `ConvaiActionTargetGroup`.

### 下一步

{% content-ref url="/pages/1398e3302b345ef93934a0e6c93b4d8e576ab00e" %}
[排查角色动作问题](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/character-actions/debugging-and-troubleshooting.md)
{% endcontent-ref %}

{% content-ref url="/pages/0341126fa4c492311dab4fb6aca6d0c64191016b" %}
[角色动作脚本参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/character-actions/actions-scripting-reference.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, and the optional `goal` query parameter:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/character-actions/usage-examples.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
