> 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).

# 角色动作示例

这六个示例从最简单的可能配置逐步过渡到完整的脚本控制。每个示例都是自包含的——你无需先阅读其他示例，也可以直接跟随任意一个。

### 示例 1——消防安全取回（Inspector 设置，无代码）

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

**前提条件：** 场景中已烘焙 NavMesh。

#### Inspector 配置

在讲师 NPC 的 `GameObject`上，添加以下组件：

* `ConvaiCharacter`
* `ConvaiActionConfigSource`
* `ConvaiActionDispatcher` （将两个策略都保持默认值：Queue、StopBatch）
* `ConvaiWalkToActionExecutor` — `_arriveDistance = 0.6`

在 `ConvaiActionConfigSource`:

**动作定义：**

| 动作名称 | 目标要求 | 执行器                          |
| ---- | ---- | ---------------------------- |
| `取回` | `对象` | `ConvaiWalkToActionExecutor` |
| `指向` | `任一` | `ConvaiLookAtActionExecutor` |

**可操作对象：**

| 名称     | 描述                        |
| ------ | ------------------------- |
| `灭火器`  | 主泵控制面板旁墙上支架上的红色便携式二氧化碳灭火器 |
| `报警面板` | 靠近场地入口安装的带红色拉手的紧急报警面板     |

**预期结果：**

* “取回灭火器” → NPC 会导航到灭火器处，并在距离 0.6 个单位的位置停下。
* “指向报警面板” → NPC 会在 0.5 秒内转身面向报警面板。
* “取回报警” → Convai 会根据描述正确地将“报警”解析为“报警面板”。

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

```
[ConvaiActionDebugProbe] 步骤成功 #1: cmd='Retrieve Extinguisher', def='Retrieve', target=Object:Extinguisher
```

{% endhint %}

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

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

#### C# 设置

连接 `OnBatchCompleted` 到检查清单管理器。如果你在 Inspector 中将其接好，调度器一侧无需额外代码。通过代码连接：

```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` |
| `演示` | `对象` | `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# 设置

将 `WaitForBotSpeech` 和 `DelayAfterBotSpeechSeconds` 在入队前，先将其设置在命令上：

```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` 事件触发——以先发生者为准——然后再等待 `DelayAfterBotSpeechSeconds` 上设置的额外 0.3 秒，之后才执行点指手势。

只有该批次的第一步会这样受门控。如果这些事件都未触发，调度器的 `_speechGateTimeoutSeconds` 字段仍会放行该步骤（默认 2 秒，在 Inspector 的 Dispatch 标题下显示为“Speech Gate Timeout Seconds”），因此静默回合不会卡住整个批次。

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

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

#### Inspector 配置

在讲师 NPC 的 `GameObject`，添加 `ConvaiMeasureDistanceActionExecutor` (`添加组件 > Convai > Actions > Measure Distance`）。它不需要同级组件——在没有解析出目标时，它会改为测量到玩家的距离。

在 `ConvaiActionConfigSource`:

**动作定义：**

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

将执行器的 **距离区间** 字段保持默认值（`触手可及` `1.2`, `几步之遥` `3.5`, `跨越整个区域` `9`），并保持 **包含米** 已勾选，这样口头回答就会包含测得的数值。

在动作定义上，将 **答案传递** 设为 `告诉玩家` ——这是 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 %}

{% content-ref url="/pages/7905d34249d33be76079e6f5bb2876a37dea1fe2" %}
[将动作迁移到 v4.5.0](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/character-actions/migrate-to-v4-5.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.
