> 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/embodiment/body-language/gestures-and-reactions.md).

# 触发手势与反应

在 Convai 角色上触发脚本化的点头、语义手势提示和一次性反应，并处理被拒绝或忙碌的请求。

在一个已经具有……的 Convai 角色上触发脚本化头部手势、语义手势提示，或一次性身体反应 `ConvaiBodyLanguageController`，并处理角色当前无法执行该手势的情况。

### 前提条件

* 一个具有 `ConvaiBodyLanguageController` (**Convai > 具身化 > 身体语言**）已经添加并运行。参见 [身体语言快速入门](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/embodiment/body-language/quick-start.md).
* 对角色上控制器的引用，可通过以下方式解析： `GetComponent<ConvaiBodyLanguageController>()`.

### 触发脚本化头部手势

调用 `Nod(HeadGestureKind kind, float intensity = 1f)` 以请求一次性 `点头`, `摇头`，或 `倾斜`。该方法返回一个 `HeadGestureHandle` 其 `完成` 任务会在程序结束时解析——自然结束、被另一个手势取代，或通过 `ClearScriptedOverrides()`.

```csharp
using Convai.Domain.Embodiment.Interfaces;
using Convai.Modules.BodyLanguage.Components;
using UnityEngine;

public class HeadGestureExample : MonoBehaviour
{
    private ConvaiBodyLanguageController _bodyLanguage;

    private void Awake()
    {
        _bodyLanguage = GetComponent<ConvaiBodyLanguageController>();
    }

    public async void NodOnce()
    {
        HeadGestureHandle handle = _bodyLanguage.Nod(HeadGestureKind.Nod, intensity: 1f);
        await handle.Completion;
    }
}
```

一个脚本化的 `点头`/`摇头` 会执行其自身的阻尼双点头确认形态，刻意比自动伴语节拍更长、更平和。脚本化请求与自动伴语节拍以及倾听倾斜保持共享同一个单一的活动/待处理槽位，因此，当角色已经处于手势中途时发出的请求可能会被拒绝。

### 处理被拒绝的头部手势

`点头` 从不返回 `null` 并且绝不会抛出异常。相反，被拒绝或不可用的请求会返回一个已完成的句柄，其中 `IsActive` 设置为 `false` 和 `拒绝原因` 被设置为以下之一： `HeadGestureRefusal` 值。忽略 `拒绝原因` 在手势无法播放时会静默无操作，因此在假定手势已运行之前请先检查它：

| `HeadGestureRefusal` | 含义                                                  | 该做什么                                                                                                                         |
| -------------------- | --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `无` (`0`)            | 请求已被接受；该句柄表示一个正在运行的程序。                              | 等待 `完成` 与平常一样。                                                                                                               |
| `Busy` (`1`)         | 角色已经在执行一个头部手势，并且后面还排了另一个。该情况是暂时性的——同样的请求在稍后片刻通常会成功。 | 稍等片刻后重试，或者跳过这一行的手势。                                                                                                          |
| `不可用` (`2`)          | 角色当前完全无法执行头部手势：没有可用的骨架、没有身体语言配置文件，或者该组件被禁用或未在播放。    | 不要重试。请修复设置问题——参见 [排查身体语言问题](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/embodiment/body-language/troubleshooting.md). |

```csharp
HeadGestureHandle handle = _bodyLanguage.Nod(HeadGestureKind.Shake, intensity: 0.8f);

if (!handle.IsActive)
{
    switch (handle.Refusal)
    {
        case HeadGestureRefusal.Busy:
            // 暂时性的——可稍后安全重试。
            break;
        case HeadGestureRefusal.Unavailable:
            // 该骨架或配置文件无法支持该手势。不要重试。
            break;
    }
}
```

{% hint style="info" %}
随附的动作执行器 `ConvaiHeadResponseActionExecutor` （菜单路径 **Convai > 动作 > 点头或摇头**）已经实现了此重试：它会等待 `Busy` 拒绝状态最多 1.5 秒，然后才让该动作步骤失败。使用它可以让点头或摇头对 Convai 的动作做出响应，而无需自己编写这段逻辑。参见 [角色动作](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/character-actions.md).
{% endhint %}

### 触发语义手势提示

`PulseGesture(GestureCue cue)` 请求一个语义手势，并优先于自动手势表现。它返回一个 `GestureCueHandle` 其 `完成` 会在提示的派发结果已知时立即解析——要么接受以执行，要么被拒绝并替换。它不会跟踪最终生成的剪辑直到其视觉结束。

```csharp
using Convai.Domain.Embodiment.Interfaces;

GestureCueHandle cue = _bodyLanguage.PulseGesture(new GestureCue(GestureCueKind.Affirmative));
await cue.Completion;
```

目前只有四个 `GestureCueKind` 值会映射到当前随附的动画内容： `肯定`, `否定`, `问候`，以及 `不确定`。其余值—— `强调`, `节拍`, `手掌朝向玩家`, `手放胸前`, `指示物体`，以及 `列举` ——是为未来的伴语和指示性手势内容保留的数据模型槽位。当前没有任何随附的动画集合会将剪辑标记为其中任意一种，因此，由保留值构建的提示始终解析为“无映射”：该请求会回退到同样的头部节拍和姿态脉冲原语 `PulseGesture` 会将其用于任何被拒绝的提示；而在完整的 Humanoid 手臂链上，则会使用一个简短的程序化手臂/手部手势。 `GestureCueKind.None` 始终会被拒绝。

### 触发反应

`TriggerReaction(ReactionKind kind, float intensity = 1f)` 触发一次性身体反应。它是即发即忘的——没有句柄，因为每个反应包络都在两秒以内运行。

```csharp
_bodyLanguage.TriggerReaction(ReactionKind.AmusementBounce, intensity: 0.8f);
```

| `ReactionKind` | 动作               | Trigger                     |
| -------------- | ---------------- | --------------------------- |
| `无` (`0`)      | 无反应。             | 无操作。                        |
| `惊讶一颤` (`1`)   | 脊柱短暂挺直，肩膀一抖。     | 自主惊讶反应，或脚本化触发。              |
| `愉悦弹动` (`2`)   | 轻微的愉悦胸部弹动。       | 自主喜悦反应，或脚本化触发。              |
| `倒吸一口气` (`3`)  | 路由到呼吸系统的倒吸一口气事件。 | 仅限脚本化，通过 `TriggerReaction`. |
| `叹气` (`4`)     | 路由到呼吸系统的叹气事件。    | 仅限脚本化，通过 `TriggerReaction`. |

其中一次只会有一个 `惊讶一颤`/`愉悦弹动` 同时播放——新的触发会替换当前正在播放的内容。每个类别都遵循其各自的配置开关（`对突发情绪作出反应`, `被打断时倒吸一口气`, `平静下来时叹气`）；已禁用的类别会被静默丢弃。

`TriggerReaction` 可以安全地在无法 tick 的控制器上调用——无论是禁用、未播放，还是由于缺少骨架而处于无效状态——它都会变成静默无操作，与 `点头` 和 `PulseGesture`的降级行为一致。

### 清除脚本化覆盖

`ClearScriptedOverrides()` 会完成所有未完成的 `点头`/`PulseGesture` 句柄，从而解除等待中的调用方阻塞，并将头部手势通道交还给自动导演（伴语节拍、倾听倾斜保持）。

```csharp
_bodyLanguage.ClearScriptedOverrides();
```

已经在运行中的自主程序会继续运行——只有控制器自身跟踪的脚本化请求会被取消。 `ClearScriptedOverrides` 是幂等的，在没有任何活动内容时调用也很安全。

### 验证设置

进入播放模式并调用 `点头`, `PulseGesture`，或 `TriggerReaction` 可通过脚本或“动作调试”窗口。角色会在其当前正在做的任何动作之上叠加播放所请求的动作——呼吸、重心转移和视线都会在下层继续进行。 `ConvaiBodyLanguageController` 检查器的 **运行时状态** 部分会在场景播放时显示当前活动的头部手势、上一次尝试的手势提示，以及当前活动的反应。

### 下一步

{% content-ref url="/pages/aa2dfbd502cd5beea5e136b8b51781cf4aa0c88c" %}
[肢体语言配置文件参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/embodiment/body-language/profile-reference.md)
{% endcontent-ref %}

{% content-ref url="/pages/0ca05e2081622e66aa066b861879b41f4427d1c9" %}
[肢体语言脚本参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/embodiment/body-language/scripting-reference.md)
{% endcontent-ref %}

{% content-ref url="/pages/36545202fce61c9549c36fc04283ca75f22dd128" %}
[肢体语言故障排查](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/embodiment/body-language/troubleshooting.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/embodiment/body-language/gestures-and-reactions.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.
