> 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/action-executors.md).

# 动作执行器

按包分组的全部 21 个内置动作执行器组件参考，包括每个 Inspector 字段、默认值和所需的配套组件。

执行器是在调度器运行某个动作步骤时执行场景内行为的组件——例如让 NPC 行走、指向、改变情绪或播放声音。Convai SDK 随附 21 个执行器组件，分为六个包。每个都带有一个 `ConvaiActionArchetype` 属性，因此从 Actions Editor 的 **+ 添加动作 ▾** 目录会自动填入它的动作名称、描述、目标需求以及任何参数——要得到一个可用的动作，无需手工编写。

全部 21 个都派生自 `ConvaiActionExecutorBase` (`Convai.Runtime.Actions`），大多数通过 `ConvaiTargetedActionExecutor` 或通用的 `ConvaiCharacterActionExecutor<TPeer>`。基于 `ConvaiCharacterActionExecutor<TPeer>` 除了下方每个执行器列出的字段之外，还会额外暴露一个 Inspector 字段—— **Character Component**，一个对 peer 组件的引用（例如 `ConvaiGazeController`）它所依赖的组件。留空则执行器会自动查找 peer，先搜索该 `游戏对象`的父级，再搜索其子级；只有当角色携带多个该 peer 类型实例时，才显式指定它。

### Flow 与 Utility 包（`Convai.Runtime`)

不依赖模块的包，位于 `SDK/Runtime/Actions/Executors/` ——这里的每个行为都可在任何项目中的任何角色上工作，无需 Convai 模块。

#### 触发 Unity 事件

运行你接入到其事件中的任何内容，然后始终成功。对于场景中已经能通过按钮完成的任何事情，这都是一种无代码的替代方案——开门、启动时间轴、奖励积分。

| 属性          | 值                                             |
| ----------- | --------------------------------------------- |
| **类**       | `ConvaiUnityEventActionExecutor`              |
| **菜单路径**    | `添加组件 → Convai → Actions → Raise Unity Event` |
| **原型动作名称**  | `触发 Unity 事件`                                 |
| **目标要求**    | 无                                             |
| **所需 peer** | 无                                             |

**Inspector 字段：**

| 字段           | 类型           | 默认 | 说明                                   |
| ------------ | ------------ | -- | ------------------------------------ |
| `_onExecute` | `UnityEvent` | 空  | 每次动作运行时都会调用。可在 Inspector 中接入任意数量的回调。 |

绝不会失败——即使什么都没接入，事件仍会报告成功；Actions Editor 会在编写时标记未接线的事件。若动作需要读取参数、耗时、可取消，或报告无法运行的原因，就编写自定义执行器。

#### 等待

暂停几秒，除此之外不做任何事。单独使用很少有用；在 **按顺序运行** 它正是让表演拥有节奏感的东西——先指向门，停顿一下，然后走过去。

| 属性          | 值                                |
| ----------- | -------------------------------- |
| **类**       | `ConvaiWaitActionExecutor`       |
| **菜单路径**    | `添加组件 → Convai → Actions → Wait` |
| **原型动作名称**  | `等待`                             |
| **目标要求**    | 无                                |
| **所需 peer** | 无                                |

**Inspector 字段：**

| 字段            | 类型      | 默认   | 说明                                                     |
| ------------- | ------- | ---- | ------------------------------------------------------ |
| `_seconds`    | `float` | `1`  | 等待多久。角色可以用 `seconds` 参数请求不同的时长。                        |
| `_maxSeconds` | `float` | `30` | 允许的最长等待时间。会同时限制 Inspector 值和角色请求的任何值，因此一个错误的数字不会让场景卡住。 |

等待是逐帧且可取消的——它从不使用 `Task.Delay` ——因此它以正常游戏速度运行，尊重暂停和时间缩放，并且在动作取消时能正确回收。

#### 按顺序运行

将多个 Action Behavior 作为一个单一动作依次运行——“问候访客”可以表示看向对方、点头并打招呼，全部无需代码编写。每一步都会接收相同的目标和参数。

| 属性          | 值                                        |
| ----------- | ---------------------------------------- |
| **类**       | `ConvaiSequenceActionExecutor`           |
| **菜单路径**    | `添加组件 → Convai → Actions → Run In Order` |
| **原型动作名称**  | `按顺序运行`                                  |
| **目标要求**    | 无（传递给每一步）                                |
| **所需 peer** | 无                                        |

**Inspector 字段：**

| 字段       | 类型                    | 默认 | 说明                                                          |
| -------- | --------------------- | -- | ----------------------------------------------------------- |
| `_steps` | `List<MonoBehaviour>` | 空  | 要运行的 Action Behavior，自上而下。每一项都必须实现 `IConvaiActionExecutor`. |

在第一个未成功的步骤处停止，并返回该步骤自身的结果，同时以前缀形式带上其位置——失败会指出是哪一步失败以及原因。若某一项为空、不是 Action Behavior，或引用了这个相同的组件，则会立即失败并返回 `ConvaiActionFailureReason.InvalidState`.

#### 显示或隐藏对象

将目标对象打开或关闭——从“给他们看地图”到让某个东西可见的最短路径，而且对象本身无需额外组件。

| 属性          | 值                                               |
| ----------- | ----------------------------------------------- |
| **类**       | `ConvaiSetActiveActionExecutor`                 |
| **菜单路径**    | `添加组件 → Convai → Actions → Show Or Hide Object` |
| **原型动作名称**  | `显示或隐藏对象`                                       |
| **目标要求**    | 对象                                              |
| **所需 peer** | 无                                               |

**Inspector 字段：**

| 字段      | 类型                                      | 默认   | 说明                               |
| ------- | --------------------------------------- | ---- | -------------------------------- |
| `_mode` | `ConvaiShowHideMode` (`显示`, `隐藏`, `切换`) | `显示` | 对对象要执行什么操作。角色可以用 `模式` 参数请求不同的时长。 |

请求对象已经处于的状态时会成功并明确说明（“已经显示。”），而不是失败——已满足的请求会被履行，而不是失败。未解析到目标时返回 `Unhandled`.

#### 播放 Animator 状态

**适用于使用自己 Animator Controller 进行动画的角色，而不是 Body Animation 模块。** 设置一个由动作名称映射而来的 Trigger 参数，并且可以选择等待结果状态结束。

| 属性          | 值                                                                          |
| ----------- | -------------------------------------------------------------------------- |
| **类**       | `ConvaiAnimatorStateActionExecutor`                                        |
| **菜单路径**    | `添加组件 → Convai → Actions → Play Animator State（使用自己的 Animator Controller）` |
| **原型动作名称**  | `播放 Animator 状态`                                                           |
| **目标要求**    | 无                                                                          |
| **所需 peer** | `Animator`                                                                 |

**Inspector 字段：**

| 字段          | 类型                                  | 默认 | 说明                           |
| ----------- | ----------------------------------- | -- | ---------------------------- |
| `_bindings` | `List<ConvaiAnimatorActionBinding>` | 空  | 该角色可通过 Animator 执行的每个动作各占一行。 |

**绑定行字段。** 每一行都在 Inspector 中配置；行类型属于 SDK 内部，因此脚本无法构造它。

| 字段                   | 类型      | 默认     | 说明                                                   |
| -------------------- | ------- | ------ | ---------------------------------------------------- |
| `ActionName`         | `字符串`   | —      | 要响应的动作名称，不区分大小写匹配。                                   |
| `TriggerName`        | `字符串`   | —      | 该动作运行时要设置的 Animator Trigger 参数。                      |
| `WaitForStateTag`    | `字符串`   | 空      | 可选。用相同的词给 Animator 状态加标签，并在动作结束前等待它。留空则在设置触发器后立即结束。  |
| `NormalizedExitTime` | `float` | `0.95` | 带标签状态到多大进度算作完成（`0`–`1`）。仅在 `WaitForStateTag` 被设置时使用。 |

没有匹配行的动作名称会被拒绝为 `Unhandled` ，而不是失败，因此角色上的另一个 Action Behavior 仍有机会响应它。如果角色有一个 `ConvaiBodyAnimationController`，拒绝消息会指明 **播放手势** 作为替代——这两个行为驱动的是同一个 Animator，如果一起使用会相互冲突。

#### 播放声音

通过一个普通的 `AudioSource`。有无目标都可用——这一选择在编写动作时决定：没有目标再加上已指定的 `AudioSource` 会直接播放声音；有目标但没有 `AudioSource` 指定时，则从角色被要求作用的对象上播放。

| 属性          | 值                                      |
| ----------- | -------------------------------------- |
| **类**       | `ConvaiPlaySoundActionExecutor`        |
| **菜单路径**    | `添加组件 → Convai → Actions → Play Sound` |
| **原型动作名称**  | `播放声音`                                 |
| **目标要求**    | 二者之一                                   |
| **所需 peer** | 无                                      |

**Inspector 字段：**

| 字段                      | 类型            | 默认     | 说明                                      |
| ----------------------- | ------------- | ------ | --------------------------------------- |
| `_audioSource`          | `AudioSource` | `null` | 通过其播放的源。留空则使用目标对象上的一个。                  |
| `_clip`                 | `AudioClip`   | `null` | 要播放的声音。留空则播放 `AudioSource` 它已经拥有的任意剪辑。  |
| `_volume`               | `float`       | `1`    | 播放音量， `0`–`1`。角色可以用 `volume` 参数请求不同的时长。 |
| `_waitForSoundToFinish` | `布尔值`         | `否`    | 保持动作打开，直到剪辑播放完毕。                        |

永远不会通过角色自己的语音播放 `AudioSource` ——借用它会让角色在一句话中途被打断。若既没有指定的源，也没有目标上的源，动作会拒绝并说明需要指定什么。没有剪辑会解析为 `Failed`.

### 注意力包（`Convai.Modules.Gaze`)

`SDK/Modules/Gaze/Executors/` ——这里的每个行为都需要一个 `ConvaiGazeController` peer。

#### 看向目标

将角色的注意力转向目标——眼睛先动，头部跟随，而当目标位于头部无法转到的位置时，身体也会转过去。只要视线明显到达就结束，而不是等持有时长结束，因此后续步骤不会排在这个保持之后。

| 属性          | 值                                          |
| ----------- | ------------------------------------------ |
| **类**       | `ConvaiLookAtActionExecutor`               |
| **菜单路径**    | `添加组件 → Convai → Actions → Look At Target` |
| **原型动作名称**  | `看向谁`                                      |
| **目标要求**    | 二者之一                                       |
| **所需 peer** | `ConvaiGazeController`                     |
| **超时**      | 10 秒（原型默认）                                 |

**Inspector 字段：**

| 字段             | 类型                                 | 默认    | 说明                                                          |
| -------------- | ---------------------------------- | ----- | ----------------------------------------------------------- |
| `_mode`        | `ConvaiGazeLookMode` (`瞥一眼`, `持续`) | `持续`  | 瞥一眼是快速看一下又移开；持续是角色保持的专注凝视，必要时还会带动身体转向。角色可以用 `模式` 参数请求不同的时长。 |
| `_holdSeconds` | `float`                            | `2.5` | 视线到达后继续看多久。 `0` 会一直看着，直到有别的东西吸引角色的注意。                       |
| `_engagement`  | `float`                            | `1`   | 注视得有多投入， `0`–`1`.                                           |

角色为了保持与交谈对象的眼神接触而拒绝的一次瞥视，会报告 `Unhandled` （眼神锁定按预期工作），而不是失败。

#### 注视玩家

与玩家保持眼神接触，直到被告知停止——这是一个有作用域、可取消的请求，区别于角色自身的会话眼神接触设置，本功能不会更改它。

| 属性          | 值                                            |
| ----------- | -------------------------------------------- |
| **类**       | `ConvaiWatchPlayerActionExecutor`            |
| **菜单路径**    | `添加组件 → Convai → Actions → Watch The Player` |
| **原型动作名称**  | `注视玩家`                                       |
| **目标要求**    | 无（默认指玩家）                                     |
| **所需 peer** | `ConvaiGazeController`                       |

**Inspector 字段：**

| 字段            | 类型                                     | 默认   | 说明                                              |
| ------------- | -------------------------------------- | ---- | ----------------------------------------------- |
| `_mode`       | `ConvaiWatchPlayerMode` (`注视`, `停止注视`) | `注视` | 此调用是开始注视还是停止注视。角色可以用 `模式` 参数（`watch` 或 `stop`). |
| `_engagement` | `float`                                | `1`  | 注视得有多专注， `0`–`1`.                               |

场景中未找到玩家会失败并返回 `ConvaiActionFailureReason.TargetMissing`。如果组件在注视过程中被禁用，注视会自动释放。

#### 扫描环境

检查周围环境中的多个不同点，优先选择搜索半径内的场景对象，若没有则回退到均匀分布的世界坐标点。

| 属性          | 值                                            |
| ----------- | -------------------------------------------- |
| **类**       | `ConvaiScanEnvironmentActionExecutor`        |
| **菜单路径**    | `添加组件 → Convai → Actions → Scan Environment` |
| **原型动作名称**  | `扫描环境`                                       |
| **目标要求**    | 无                                            |
| **所需 peer** | `ConvaiGazeController`                       |
| **超时**      | 15 秒（原型默认）                                   |

**Inspector 字段：**

| 字段                  | 类型          | 默认    | 说明                                |
| ------------------- | ----------- | ----- | --------------------------------- |
| `_durationSeconds`  | `float`     | `3.5` | 扫描总时长。角色可以用 `duration` 参数请求不同的时长。 |
| `_stopCount`        | `整数`        | `4`   | 视线停顿的不同点数量， `2`–`8`.              |
| `_arcDegrees`       | `float`     | `150` | 覆盖的水平范围，以角色正前方为中心， `20`–`320`.    |
| `_allowBodyTurn`    | `布尔值`       | `否`   | 宽范围扫描点是否可以让身体连同头和眼一起转动。           |
| `_searchRadius`     | `float`     | `7`   | 用于查找值得检查的场景碰撞体的半径。 `0` 仅使用生成的点。   |
| `_targetLayers`     | `LayerMask` | 全部    | 包含可被选作扫描点的对象的图层。                  |
| `_fallbackDistance` | `float`     | `4`   | 当没有场景对象适合该弧度时，生成扫描点的距离。           |
| `_fallbackHeight`   | `float`     | `1.5` | 生成的扫描点相对于角色原点的高度。                 |

仅在 Play 模式下运行——它驱动实时凝视 rig，因此在 `Unhandled` Edit 模式中会拒绝。保持的凝视会在完成、取消、禁用或销毁时释放。

### 表情包（`Convai.Modules.Emotion`, `Convai.Modules.BodyLanguage`)

Set Mood 和 React 位于 `SDK/Modules/Emotion/Executors/` 并且需要一个 `ConvaiEmotionController` peer。Nod Or Shake Head 位于 `SDK/Modules/BodyLanguage/Executors/` 并且需要一个 `ConvaiBodyLanguageController` peer。

#### 设置情绪

持续型：让角色平滑进入一种新情绪，并保持在那里，直到有别的东西改变它。用于会影响余下对话的情绪转变。

| 属性          | 值                                    |
| ----------- | ------------------------------------ |
| **类**       | `ConvaiSetMoodActionExecutor`        |
| **菜单路径**    | `添加组件 → Convai → Actions → Set Mood` |
| **原型动作名称**  | `设置情绪`                               |
| **目标要求**    | 无                                    |
| **所需 peer** | `ConvaiEmotionController`            |

**Inspector 字段：**

| 字段                   | 类型           | 默认    | 说明                                       |
| -------------------- | ------------ | ----- | ---------------------------------------- |
| `_defaultMood`       | `字符串` （情绪标签） | 空     | 角色未指定时使用的情绪。通常由 `mood` 参数来驱动它。           |
| `_defaultIntensity`  | `float`      | `0.6` | 强度， `0`–`1`。角色可以用 `intensity` 参数请求不同的时长。 |
| `_transitionSeconds` | `float`      | `1.5` | 变化需要多长时间。                                |

角色没有的情绪会失败，并列出它已有的情绪——否则情绪系统会把未知情绪当作中性，这样就会在什么都没做的情况下报告成功。对于瞬时反应，请使用 **React** 而不是这个；如果用 Set Mood 来表示短暂一瞬，角色会被卡在那个情绪里。

#### React

瞬时型：表现一下、维持一下，然后恢复到角色之前的感受——一阵退缩、一闪而过的喜悦、一个痛苦的表情。即使动作在中途被取消，恢复也会得到保证。

| 属性          | 值                                 |
| ----------- | --------------------------------- |
| **类**       | `ConvaiReactActionExecutor`       |
| **菜单路径**    | `添加组件 → Convai → Actions → React` |
| **原型动作名称**  | `React`                           |
| **目标要求**    | 无                                 |
| **所需 peer** | `ConvaiEmotionController`         |

**Inspector 字段：**

| 字段                  | 类型           | 默认     | 说明                                 |
| ------------------- | ------------ | ------ | ---------------------------------- |
| `_defaultReaction`  | `字符串` （情绪标签） | 空      | 角色未指定时使用的反应。通常由 `reaction` 参数来驱动它。 |
| `_defaultIntensity` | `float`      | `0.85` | 强度， `0`–`1`.                       |
| `_holdSeconds`      | `float`      | `1.5`  | 反应在恢复前持续多长时间。                      |

角色没有的反应会失败，并列出它已有的反应——与 Set Mood 的原因相同。

#### 点头或摇头

用头部来回答：点头表示是，摇头表示否，倾斜表示“让我想想”。这是叠加在身体当前动作之上的，所以不会看起来像木偶抽动。

| 属性          | 值                                             |
| ----------- | --------------------------------------------- |
| **类**       | `ConvaiHeadResponseActionExecutor`            |
| **菜单路径**    | `添加组件 → Convai → Actions → Nod Or Shake Head` |
| **原型动作名称**  | `点头或摇头`                                       |
| **目标要求**    | 无                                             |
| **所需 peer** | `ConvaiBodyLanguageController`                |

**Inspector 字段：**

| 字段           | 类型                                   | 默认   | 说明                                                                 |
| ------------ | ------------------------------------ | ---- | ------------------------------------------------------------------ |
| `_response`  | `HeadGestureKind` (`点头`, `摇头`, `倾斜`) | `点头` | 角色未指定时要给出的回应。角色可以请求 `yes`, `no`，或 `maybe` 通过 `response` 参数请求不同的时长。 |
| `_intensity` | `float`                              | `1`  | 动作幅度有多大， `0`–`1`.                                                  |

在手势完成前保持开启，因此一个序列可以先点头再说话，按这个顺序进行。如果头部仍在完成上一个手势，执行器会重试最多 1.5 秒，然后才以 `ConvaiActionFailureReason.Busy`.

### 手势包（`Convai.Modules.BodyAnimation`)

`SDK/Modules/BodyAnimation/Executors/` ——内容驱动：这两种行为都播放在角色 Animation Set 中编写的剪辑，因此没有这些内容的角色无法执行它们。

#### 播放手势

按名称播放角色的某个手势——挥手、耸肩、鞠躬——在当前姿态之上融合进入，再淡出回去。

| 属性          | 值                                        |
| ----------- | ---------------------------------------- |
| **类**       | `ConvaiPlayGestureActionExecutor`        |
| **菜单路径**    | `添加组件 → Convai → Actions → Play Gesture` |
| **原型动作名称**  | `播放手势`                                   |
| **目标要求**    | 无                                        |
| **所需 peer** | `ConvaiBodyAnimationController`          |
| **超时**      | 15 秒（原型默认）                               |

**Inspector 字段：**

| 字段                | 类型      | 默认  | 说明                                                 |
| ----------------- | ------- | --- | -------------------------------------------------- |
| `_defaultGesture` | `字符串`   | 空   | 角色未指定时要播放的手势。与 Animation Set 的手势名称和别名匹配。           |
| `_holdSeconds`    | `float` | `8` | 本来会无限持续下去的手势（如舞蹈、思考姿势）要保持多久。 `0` 一直保持，直到有别的东西将其停止。 |

未知手势名称会被拒绝为 `Unhandled`；Animation Set 的真实手势名称会在 Detail 追踪详细级别下记录一次。使用普通 Animator Controller 而不是 Body Animation 模块的角色则需要 **播放 Animator 状态** 改为此项。

#### 指向目标

指向动作所命名的那个东西，并根据目标实际所在位置选择使用哪只手臂；身体其余部分继续在底下做原本的动作。

| 属性          | 值                                           |
| ----------- | ------------------------------------------- |
| **类**       | `ConvaiPointAtActionExecutor`               |
| **菜单路径**    | `添加组件 → Convai → Actions → Point At Target` |
| **原型动作名称**  | `指向`                                        |
| **目标要求**    | 二者之一                                        |
| **所需 peer** | `ConvaiBodyAnimationController`             |
| **超时**      | 15 秒（原型默认）                                  |

**Inspector 字段：**

| 字段              | 类型                                    | 默认     | 说明                                                               |
| --------------- | ------------------------------------- | ------ | ---------------------------------------------------------------- |
| `_holdSeconds`  | `float`                               | `3`    | 指向保持多久 **在完全伸展时** ——只是手势中间的停顿而已。                                 |
| `_gestureSpeed` | `float`                               | `1`    | 手臂上抬和放下的速度，以动画自身速度的倍数表示， `0.25`–`3`。不影响 `_holdSeconds`.          |
| `_release`      | `PointingReleaseStyle` (`播放尾段`, `混合`) | `播放尾段` | 保持结束时会发生什么。 `播放尾段` 会在动画剪辑剩余部分中将手臂放下； `混合` 则直接退出姿势，大致在保持结束时就结束手势。 |

{% hint style="warning" %}
**`_holdSeconds` 仅仅是完全伸展时的停顿，而不是整个手势的时长。** 手臂的抬起和放下遵循动画剪辑自身的时间，在随附的指向剪辑中上下各大约会增加 2.5 秒，因此一个 `_holdSeconds` 的 `1` 仍会产生大约 6 秒长的手势。 `_gestureSpeed` 和 `_release` 直接控制抬起/放下。将 `_release` 移动到 `混合` 设为可实现的最短指向。
{% endhint %}

Animation Set 中没有指向剪辑会被拒绝为 `Unhandled`。没有解析到目标也会以同样方式拒绝——指向总是需要目标。

### 移动包（`Convai.Modules.BodyAnimation`)

`SDK/Modules/BodyAnimation/Executors/` ——这里的每个行为都需要一个 `ConvaiNavMeshLocomotion` peer，除 **转身面对目标**外，它不需要 NavMesh。

#### 走向目标

走到目标处，绕过障碍物并在一个舒适的距离前停下，而不是直接走到物体里。

| 属性          | 值                                          |
| ----------- | ------------------------------------------ |
| **类**       | `ConvaiWalkToActionExecutor`               |
| **菜单路径**    | `添加组件 → Convai → Actions → Walk To Target` |
| **原型动作名称**  | `走向`                                       |
| **目标要求**    | 二者之一                                       |
| **所需 peer** | `ConvaiNavMeshLocomotion`                  |
| **超时**      | 45 秒（原型默认）                                 |

**Inspector 字段：**

| 字段                | 类型      | 默认  | 说明                                                |
| ----------------- | ------- | --- | ------------------------------------------------- |
| `_arriveDistance` | `float` | `1` | 距离目标多远时停下，以米为单位。角色可以用 `arriveDistance` 参数请求不同的时长。 |

没有烘焙 NavMesh，或者目标不在网格上，会失败并返回 `ConvaiActionFailureReason.PathBlocked` 并指出目的地。需要已烘焙的 NavMesh。

#### 引导玩家到目标

引导玩家前往目的地：会走在前面；当玩家落后时停下；当玩家赶上时继续前进。

| 属性          | 值                                |
| ----------- | -------------------------------- |
| **类**       | `ConvaiLeadPlayerActionExecutor` |
| **菜单路径**    | `添加组件 → Convai → 动作 → 引导玩家到目标`   |
| **原型动作名称**  | `引导玩家`                           |
| **目标要求**    | 二者之一                             |
| **所需 peer** | `ConvaiNavMeshLocomotion`        |
| **超时**      | 120秒（原型默认值）                      |

**Inspector 字段：**

| 字段                      | 类型      | 默认    | 说明                         |
| ----------------------- | ------- | ----- | -------------------------- |
| `_arriveDistance`       | `float` | `1.4` | 角色会在距离目的地多远处停下。            |
| `_waitWhenFartherThan`  | `float` | `4.5` | 当玩家距离超过此值时暂停行程。            |
| `_resumeWhenCloserThan` | `float` | `2.8` | 当玩家回到此距离内时恢复行程。            |
| `_maximumWaitSeconds`   | `float` | `12`  | 在没有玩家的情况下继续前往目的地之前，最长等待时间。 |

场景中没有玩家时失败，返回 `ConvaiActionFailureReason.TargetMissing`。无法到达目的地的路径失败，返回 `PathBlocked`.

#### 转身面对目标

原地转身面向目标，而不朝其走去——大多数情况下，“看向顾客”指的是这个，而不是穿过房间。无需 NavMesh。

| 属性          | 值                                |
| ----------- | -------------------------------- |
| **类**       | `ConvaiTurnToFaceActionExecutor` |
| **菜单路径**    | `添加组件 → Convai → 动作 → 转向面对目标`    |
| **原型动作名称**  | `转向面对`                           |
| **目标要求**    | 二者之一                             |
| **所需 peer** | `ConvaiBodyAnimationController`  |
| **超时**      | 10 秒（原型默认）                       |

**Inspector 字段：**

| 字段                   | 类型                                 | 默认     | 说明                                                               |
| -------------------- | ---------------------------------- | ------ | ---------------------------------------------------------------- |
| `_turnStyle`         | `ConvaiTurnStyle` (`分步转身`, `平滑旋转`) | `分步转身` | `分步转身` 播放角色自己的转身动画； `平滑旋转` 直接旋转完成 `_smoothTurnSeconds` 且不需要动画片段。 |
| `_smoothTurnSeconds` | `float`                            | `0.5`  | 一个……的持续时间 `平滑旋转` 转身。被……忽略 `分步转身`.                                |
| `_toleranceDegrees`  | `float`                            | `8`    | 面向目标达到多近才算完成， `0`–`45`.                                          |

`分步转身` 在动画集中没有转身片段时会降级为 `Unhandled`，命名为 `平滑旋转` 作为替代方案。

#### 跟随玩家

“跟我来。”保持舒适距离；当玩家走开时缩短距离；当他们停下时原地不动。

| 属性          | 值                                  |
| ----------- | ---------------------------------- |
| **类**       | `ConvaiFollowPlayerActionExecutor` |
| **菜单路径**    | `添加组件 → Convai → 动作 → 跟随玩家`        |
| **原型动作名称**  | `跟随玩家`                             |
| **目标要求**    | 无（默认指玩家）                           |
| **所需 peer** | `ConvaiNavMeshLocomotion`          |

**Inspector 字段：**

| 字段                | 类型                                  | 默认       | 说明                                                 |
| ----------------- | ----------------------------------- | -------- | -------------------------------------------------- |
| `_mode`           | `ConvaiFollowMode` (`Follow`, `停止`) | `Follow` | 这次调用是开始跟随还是停止跟随。角色可以通过 `模式` 参数（`follow` 或 `stop`). |
| `_followDistance` | `float`                             | `2.2`    | 角色尝试与玩家保持的距离。                                      |
| `_slack`          | `float`                             | `0.8`    | 玩家必须移动超过多少距离之后， `_followDistance` 角色才会缩短间距。        |

{% hint style="info" %}
**跟随没有自然结束点。** 该动作会在角色开始跟随时立即报告成功，而跟随后续会继续进行——否则它会一直保持未结束状态直到超时，并阻塞之后的所有动作。再次发送该动作，并将 `mode: stop`，或者禁用该角色，即可结束。正在跟随的角色仍会响应其他移动动作（Walk To Target、Return To Start）：在其未发起的任何移动期间，跟随会暂停；当该移动结束后，它会在玩家旁边恢复跟随。
{% endhint %}

未找到玩家时失败，返回 `ConvaiActionFailureReason.TargetMissing`.

#### 返回起点

走回角色开始的位置——或你选择的位置——并可选地恢复初始朝向。本包中其他所有内容的撤销动作。

| 属性          | 值                                   |
| ----------- | ----------------------------------- |
| **类**       | `ConvaiReturnToStartActionExecutor` |
| **菜单路径**    | `添加组件 → Convai → 动作 → 返回起点`         |
| **原型动作名称**  | `返回起点`                              |
| **目标要求**    | 无                                   |
| **所需 peer** | `ConvaiNavMeshLocomotion`           |

**Inspector 字段：**

| 字段                 | 类型          | 默认     | 说明                          |
| ------------------ | ----------- | ------ | --------------------------- |
| `_homeSpot`        | `Transform` | `null` | “返回”指向哪里。留空则使用场景开始时角色所在的位置。 |
| `_restoreFacing`   | `布尔值`       | `是`    | 到达后转回原始朝向。                  |
| `_turnBackSeconds` | `float`     | `0.6`  | 最后那次转身需要多长时间。               |
| `_arriveDistance`  | `float`     | `0.2`  | 距离多近算作到家。                   |

起始位置记录在 `Awake`中，在角色的其他任何内容能移动它之前。找不到返回路径时失败，返回 `PathBlocked`.

### 观察包（`Convai.Runtime`)

`SDK/Runtime/Actions/Executors/` 包含观察类执行器。两种行为都通过 `ConvaiActionExecutionResult.Answered` 返回答案，并默认使用 `AnswerDelivery = TellThePlayer` ，因此除非你更改该动作的 **完成时** 设置，否则角色会说出结果。

#### 统计目标组

统计一个 `ConvaiActionTargetGroup` 中已启用的成员，并用结果作答——“还剩多少箱子。”

| 属性          | 值                                             |
| ----------- | --------------------------------------------- |
| **类**       | `ConvaiCountTargetGroupActionExecutor`        |
| **菜单路径**    | `添加组件 → Convai → 动作 → 统计目标组`                  |
| **原型动作名称**  | `统计目标组`                                       |
| **目标要求**    | 对象                                            |
| **所需的目标组件** | `ConvaiActionTargetGroup`，位于已解析的目标对象上（而不是角色上） |

**Inspector 字段：**

| 字段                      | 类型    | 默认  | 说明                                  |
| ----------------------- | ----- | --- | ----------------------------------- |
| `_availableMembersOnly` | `布尔值` | `是` | 计数时忽略已禁用的成员组件和未激活的成员对象。             |
| `_includeMemberNames`   | `布尔值` | `是` | 在答案中同时包含成员名称和计数。                    |
| `_memberLabel`          | `字符串` | 空   | 可选复数标签，例如 `“crates”`。留空则使用目标组自己的名称。 |

一个已解析的目标，若没有 `ConvaiActionTargetGroup` 组件，或一个空组，则会失败，返回 `Unhandled` 而不是报告误导性的零。

#### 测量距离

测量角色到目标的地面平面距离；如果未指定目标，则测量到玩家的距离，并用通俗表达作答——“大约 3 米远。”

| 属性          | 值                                     |
| ----------- | ------------------------------------- |
| **类**       | `ConvaiMeasureDistanceActionExecutor` |
| **菜单路径**    | `添加组件 → Convai → 动作 → 测量距离`           |
| **原型动作名称**  | `测量距离`                                |
| **目标要求**    | 二者之一                                  |
| **所需 peer** | 无                                     |

**Inspector 字段：**

| 字段                   | 类型      | 默认    | 说明                              |
| -------------------- | ------- | ----- | ------------------------------- |
| `_withinReachMetres` | `float` | `1.2` | 不超过此值的距离描述为“触手可及”。              |
| `_aFewStepsMetres`   | `float` | `3.5` | 不超过此值的距离描述为“几步之遥”。              |
| `_acrossAreaMetres`  | `float` | `9`   | 不超过此值的距离描述为“在区域对面”。超过此值则为：“很远。” |
| `_includeMetres`     | `布尔值`   | `是`   | 在答案中包含以米为单位的测量值。                |

场景中既没有目标也没有玩家时失败，返回 `ConvaiActionFailureReason.TargetMissing`.

### 选择合适的执行器

| 使用场景                             | 推荐执行器                                                                                                                   |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| 无代码接入现有玩法                        | 触发 Unity 事件                                                                                                             |
| 控制一系列动作的节奏，或在步骤之间暂停              | 等待                                                                                                                      |
| 将多个行为串联为一个动作                     | 按顺序运行                                                                                                                   |
| 切换场景对象的可见性                       | 显示或隐藏对象                                                                                                                 |
| 角色使用自己的 Animator Controller 播放动画 | 播放 Animator 状态                                                                                                          |
| 播放一次性声音，可带目标或不带目标                | 播放声音                                                                                                                    |
| 将角色视线转向目标                        | 看向目标                                                                                                                    |
| 按请求与玩家保持眼神接触                     | 注视玩家                                                                                                                    |
| 明显地查看周围区域                        | 扫描环境                                                                                                                    |
| 改变角色当前的情绪状态                      | 设置情绪                                                                                                                    |
| 一瞬即逝的情绪片段                        | React                                                                                                                   |
| 用头部表示“是”“否”或“让我想想”               | 点头或摇头                                                                                                                   |
| 播放动画集中指定的手势                      | 播放手势                                                                                                                    |
| 指向指定的人、地点或物体                     | 指向目标                                                                                                                    |
| 使用寻路导航到目标                        | 走向目标                                                                                                                    |
| 引导玩家前往某处                         | 引导玩家到目标                                                                                                                 |
| 原地转身面向目标                         | 转身面对目标                                                                                                                  |
| 随玩家移动而陪同前行                       | 跟随玩家                                                                                                                    |
| 撤销移动——走回起点                       | 返回起点                                                                                                                    |
| 统计可用的已知对象数量                      | 统计目标组                                                                                                                   |
| 回答“那个有多远”                        | 测量距离                                                                                                                    |
| 已发布的执行器未涵盖的玩法                    | [编写自定义动作执行器](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/character-actions/writing-custom-executors.md) |

### 下一步

{% content-ref url="/pages/6e3c85bad169c9c2c755b38be39008ef3ce023cf" %}
[分发器和批处理策略](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/character-actions/dispatcher-and-batch-policies.md)
{% endcontent-ref %}

{% content-ref url="/pages/c5598abd0ddd72fa75a0989ad602a5b4d12e16d7" %}
[编写自定义动作执行器](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/character-actions/writing-custom-executors.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/action-executors.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.
