> 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/unreal-engine-plugin-beta-overview/convai-actions/phase-2-custom-actions.md).

# 阶段 2：自定义动作

声明你自己的无参数动作，为其绑定 Blueprint 处理程序，按动作名称分发，并确认角色会按请求运行你的代码。

第 1 阶段使用了随附的四个默认动作。现在你将添加你的 **自定义动作** ，不带参数，并将其连接到一个 Blueprint 事件。到本阶段结束时，向机器人询问 *"打印 hello"* 将会运行你的 Blueprint 代码。

### 你需要准备的内容

* 第 1 阶段的设置已生效——关卡中有聊天机器人， `启用动作` 已勾选，NavMesh 已就位，角色移动已设置。
* 角色 Blueprint 资源已打开（或可访问）。

### 第 1 步——声明动作模板

1. 选中关卡中的 Convai 角色 Actor。
2. 在 Details 面板中，找到 **Convai 聊天机器人** 组件 → **Convai → 动作 → 环境 → 动作**.
3. 点击 **`+`** 以添加一个新条目。UE 会展开一个 `FConvaiAction` 结构体。
4. 填写：
   * **名称**: `打印` （这是你的处理器将据此分发的规范动作名称）。
   * **描述**: `在屏幕上打印一条调试消息`.
   * 保留 **`Parameters`** 为空。

该 **`Rendered String`** 下方字段会自动填入：

```
Print — 在屏幕上打印一条调试消息。
```

这就是发送给 LLM 的线格式字符串。当你编辑 Name 或 Description 时，渲染后的字符串会实时更新。

### 第 2 步——在 Blueprint 中绑定处理器

聊天机器人会触发 `OnActionReceivedEvent_V2` 每当机器人决定执行操作时都会触发。你在角色的 Blueprint 中对此作出响应。

1. 打开你的角色蓝图。
2. 在 **组件** 选项卡，点击 **Convai 聊天机器人** 组件以选中它。
3. 在 **详情** 在该组件的面板中，找到 **事件** 类别。点击 **`+`** 旁边的 **`On Action Received Event V2`**。UE 会在 Event Graph 中放入一个已绑定事件。
4. 该事件会传递一个 **`动作序列`** 数组（每个条目都是一个 `FConvaiResultAction`）以及对 Chatbot Component 和交互中的 Player Component 的引用。

### 第 3 步——按动作名称分发

在绑定事件内部， **对每个** 数组中的动作：

1. **获取** `Action` （规范名称字符串）。
2. **按字符串切换** 并为你声明的每个动作设置 case：
   * `打印` → 调用你的自定义逻辑，然后 `Handle Action Completion(Is Successful=true, Delay=0)`.
   * **默认值** → 调用 `Handle Action Completion(Is Successful=true, Delay=0)` 以保持队列继续推进（或者让未处理的动作重试——那是一个 `Is Successful=false` 情况）。

对于 `打印` 情况：

1. 拖出一个 **`Print String`** 节点从执行引脚拉出，并向其传入一个字面量 `"来自 Convai 的你好！"` （或者从 Action 中读取——但在这个阶段，动作没有参数）。
2. 打印之后，拖入 **`处理动作完成`** 从聊天机器人引用上。设置：
   * **是否成功**: `true` （动作已运行）。
   * **延迟**: `0`.
   * 保留 **事件文本** 为空（高级字段）——用于你希望将结果推回机器人动态上下文时。为空 = 没有事件。

这就是完整的处理器。机器人现在知道如何执行 `打印`.

### 第 4 步——试玩测试

按下 **播放** 并向角色询问： *"打印 hello。"*

在编辑器的视口中，你应该会看到 `"来自 Convai 的你好！"` （或你使用的任何字面量）通过 Print String 显示出来。机器人还会说出它的确认。

### 整个流程如何端到端运行

当 LLM 发出一个动作时：

1. 服务器发送 `{name: "Print"}` （无目标，无参数）。
2. 插件的解析器会找到 `打印` 按名称在你的 `Environment.Actions`.
3. 由于该模板没有声明参数， `Parameters` 保持为空。
4. `OnActionReceivedEvent_V2` 会把解析后的序列触发到聊天机器人上。
5. 你的 Blueprint 通过 `Action == "Print"` 并执行打印。
6. `Handle Action Completion(true, 0)` 推进队列。如果序列中还有更多动作，接下来就会运行下一个。

### 队列存在的原因

机器人可以发出 **一个序列** 的动作，作为一次响应，例如 *"等待 2 秒，然后走到立方体旁，再打印完成。"* 队列可确保每个动作在下一个开始之前完成。你的处理器负责告诉队列当前动作何时完成——这就是 `处理动作完成` 所做的。

| 调用                                    | 效果                   |
| ------------------------------------- | -------------------- |
| `Handle Action Completion(true, 0)`   | 将当前动作标记为成功，立即运行下一个。  |
| `Handle Action Completion(true, 1.5)` | 成功，但在下一个动作前等待 1.5 秒。 |
| `Handle Action Completion(false, 0)`  | 重试相同的动作。             |

你也可以在同一次调用中将结果事件推入机器人的上下文——这对叙述很有用：

```
Handle Action Completion(true, 0, EventText="已打印消息", ShouldRespond=Auto)
```

### 当事情出错时

如果你的处理器无法恢复（目标消失、前置条件失败），不要无限重试—— **中止整个序列** 并让 LLM 重新规划：

```
Abort Action Sequence(EventText="无法打印——屏幕已关闭", ShouldRespond=Always)
```

这会清除队列中剩余的动作，并触发一个上下文事件，使 LLM 确认情况，并很可能在下一轮发出新的动作计划。

### 回顾

你添加了一个动作模板，编写了一个处理器，并让机器人执行自定义操作。下一步是 **类型化参数** ——告诉 LLM 一个动作接受一个数字、一个演员引用或 N 选 1 的选项。继续进入第 3 阶段——带参数的动作。


---

# 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/unreal-engine-plugin-beta-overview/convai-actions/phase-2-custom-actions.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.
