> 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-unreal-engine-plugin/features/character-actions/building-custom-action-handlers.md).

# 构建自定义动作处理器

添加自定义动作模板，使用编辑器实用工具脚手架创建 Blueprint 处理器，并报告完成以推进队列。

自定义动作处理器是 NPC Actor 上的 Blueprint 函数或事件，当队列中收到匹配的动作名称时，插件会调用它们。在 chatbot 中声明该动作，在角色 Blueprint 中搭建一个处理器框架，执行你的逻辑，然后调用 `处理动作完成` 这样队列才能继续前进。

### 前提条件

* 已在 chatbot 上启用了角色动作。参见 [角色动作快速入门](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/character-actions/character-actions-quick-start.md).
* 你知道要添加的动作名称与处理器名称完全一致，包括空格。

### 声明动作模板

{% stepper %}
{% step %}

#### 向 Actions 数组添加一项

选择 NPC Actor。在下方 **Convai | Actions > Environment > Actions**，点击 **+**.

设置 **名称** 到一个唯一的动词短语，例如 `“Print”`。将 **说明** 设置为给 Convai 的简短提示，例如 `“Print a debug message to the screen”`。将 **参数** 留空，适用于无参数动作。
{% endstep %}

{% step %}

#### 编译 Blueprint

点击 **编译** 在角色 Blueprint 上，以便在连接处理器之前保存新的动作模板。
{% endstep %}
{% endstepper %}

{% hint style="info" %}
保持动作名称和描述简短。冗长的描述会增加发送给 Convai 的上下文，而不会改善行为。将 **说明** 留空，当动作名称已经不言自明时。
{% endhint %}

### 使用 Create Convai Action Handler 搭建处理器框架

该 `ConvaiEditor` 模块会添加一个 **创建 Convai Action Handler** 条目到 Blueprint 图表上下文菜单中。用它来生成名称正确且参数类型正确的处理器。

{% stepper %}
{% step %}

#### 打开角色 Blueprint 的事件图表

打开拥有该项的 NPC Actor Blueprint `Convai Chatbot` 组件。
{% endstep %}

{% step %}

#### 创建处理器

在……中右键单击 **事件图表** 并搜索 **创建 Convai Action Handler**.

选择你添加的动作（例如 `Print`），选择 **Event（在 Event Graph 上）** 或 **Function（新函数图）**，然后确认创建。该工具会添加一个与动作名称完全相同的处理器，并带有一个 `FConvaiResultAction` 输入，并连接一个 `处理动作完成` 调用在末尾。
{% endstep %}

{% step %}

#### 在事件与完成之间添加处理器逻辑

将你的行为连接在事件引脚和 `处理动作完成`之间。对于一个 `Print` 动作，添加一个 **Print String** 节点，并使用类似于以下的字面消息 `“这是打印动作”`.
{% endstep %}
{% endstepper %}

你也可以手动创建处理器：添加一个 **自定义事件** ，其名称与动作名称完全一致，并带有一个 `FConvaiResultAction` 参数。插件按名称分发——参见 [角色动作的工作原理](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/character-actions/how-character-actions-work.md).

### 处理动作完成

每个处理器都必须调用 `处理动作完成` 在 `Convai Chatbot` 组件，当动作完成、成功、失败或被中断时。如果没有这个调用，队列会停滞，后续动作将永远不会运行。

{% hint style="info" %}
对于大多数处理器，只需要 `IsSuccessful` 需要更改。其余参数是高级选项——在你需要角色的语音反馈之前，保持它们的默认值。
{% endhint %}

| 参数               | 默认值     | 作用                                   |
| ---------------- | ------- | ------------------------------------ |
| `IsSuccessful`   | `true`  | `true` 出队当前动作并开始下一个。 `false` 清空剩余队列。 |
| `bAutoReport`    | `true`  | 当 `true`，会向 Convai 发送默认结果消息。         |
| `ShouldRespond`  | `Never` | 控制 Convai 是否会口头说明结果。                 |
| `AdditionalNote` | `""`    | 追加到自动生成消息中的可选文本。高级引脚。                |
| `延迟`             | `0.0`   | 在下一个动作开始前等待的秒数。高级引脚。                 |

#### 何时更改 Auto Report

对于不需要口头后续反馈的简单动作，将 `bAutoReport` 保持默认值，或设置为 `ShouldRespond` 到 `Never`。角色仍会收到有关结果的静默上下文。

禁用或调整 `bAutoReport` 当：

* 该动作是调试或仅限 UI 的步骤（例如 `Print`).
* 你希望 Convai 口头确认失败——将 `ShouldRespond` 到 `Always` 并提供一个 `AdditionalNote`.

#### 在每条退出路径上完成

连接 `处理动作完成` 在所有分支上：

* 动作完成后的成功路径。
* 当前置条件不满足时的失败路径。
* 当潜在动作（动画蒙太奇、计时器、移动）被取消时的中断路径。

```
// Blueprint 伪代码 — Print 处理器
事件 Print(ActionData: FConvaiResultAction)
    Print String("这是打印动作")
    HandleActionCompletion(
        IsSuccessful = true,
        bAutoReport = true,
        ShouldRespond = Never
    )
```

### 中止动作序列

当处理器无法恢复——目标 Actor 已被销毁、蒙太奇播放失败、前置条件永久无法满足——请调用 `中止动作序列` 而不是重试 `处理动作完成(false)`.

| 参数              | 默认值  | 作用                                     |
| --------------- | ---- | -------------------------------------- |
| `事件文本`          | `""` | 失败内容的描述。留空会导致静默中止。                     |
| `ShouldRespond` | `自动` | Convai 应如何反应。使用 `Always` 当角色应当口头确认失败时。 |

### 使用 On Actions Received 观察动作

绑定到 **On Actions Received** 在 chatbot 组件上，以记录或调试原始动作序列。此委托并不会取代基于名称的分发——插件仍会自动调用匹配的处理器。

```
// Blueprint 伪代码
On Actions Received(
    ChatbotComponent: UConvaiChatbotComponent,
    InteractingPlayerComponent: UConvaiPlayerComponent,
    SequenceOfActions: TArray<FConvaiResultAction>
)
```

将此委托用于诊断，而不是替代逐个动作的处理器。

### 示例：Open Door 处理器

```
// Blueprint 伪代码
事件 Open Door(ActionData: FConvaiResultAction)
    TargetEntry = GetParamAsRef(ActionData, "target")
    DoorActor = TargetEntry.Ref

    如果 DoorActor 无效：
        AbortActionSequence(
            EventText = "门目标缺失",
            ShouldRespond = Always
        )
        返回

    在 DoorActor 上调用 OpenAnimation
    延迟 1.5 秒

    HandleActionCompletion(
        IsSuccessful = true,
        bAutoReport = true,
        ShouldRespond = Never
    )
```

### 下一步

{% content-ref url="/pages/e29ff52f0d30b08b7f190e5b10f7b84aa21c7ff4" %}
[参数化动作](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/character-actions/parameterized-actions.md)
{% endcontent-ref %}

{% content-ref url="/pages/8e18d509947b40274dca96b384f432486348198f" %}
[动作 Blueprint 参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/character-actions/actions-blueprint-reference.md)
{% endcontent-ref %}

{% content-ref url="/pages/667b43e0827e11f62e187182ca1631dcc064fb61" %}
[角色动作示例](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/character-actions/character-actions-examples.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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/character-actions/building-custom-action-handlers.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
