> 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）
* `NavMeshMoveToActionExecutor` — `_stoppingDistance = 0.6`

在 `ConvaiActionConfigSource`:

**动作定义：**

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

**可作用对象：**

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

**预期结果：**

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

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

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

{% endhint %}

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

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

#### C# 设置

连接 `OnBatchCompleted` 到清单管理器。如果你在 Inspector 中进行连线，则 dispatcher 端无需额外代码。对于通过代码连线：

```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 定义：**

| 动作名称          | 目标要求 | 执行器                           |
| ------------- | ---- | ----------------------------- |
| `Walk To`     | `对象` | `NavMeshMoveToActionExecutor` |
| `Demonstrate` | `对象` | `LookAtTargetActionExecutor`  |

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

**预期结果：** 受训者说“给我看看档案系统。”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` 未能完成路径时，执行器返回 `失败`，以及 `OnStepFailed` 会触发。回退事件被注入后，NPC 会说出类似“我无法到达化学品存储区——路径被脚手架挡住了。”的话。

{% hint style="info" %}
设置 `FailurePolicy` 到 `StopBatch` （默认）这样同一批次中的后续步骤（例如“Demonstrate hazard”）就不会在导航步骤失败时继续执行。
{% endhint %}

### 示例 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 %}

### 下一步

{% 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:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/character-actions/usage-examples.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.
