> 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/gaze/scripted-gaze.md).

# 脚本控制的视线

从代码中将 Convai 角色的视线指向某个 Transform 或点，并等待结果，以便在命中后再触发后续动作。

在代码中将角色的目光指向某个 Transform 或世界空间中的点，并使用返回的句柄来判断注视何时已就位。当过场动画节拍、动作执行器或 UI 事件需要控制角色看向哪里，而不是依赖目光策略已提供的自动瞄准时，请使用本页。

### 前提条件

* `ConvaiGazeController` 已添加到角色（`Convai/具身/凝视`).
* 角色的 `ConvaiGazeController`，通过 `GetComponent<ConvaiGazeController>()` 或一个序列化字段。

### 请求一次脚本化注视

调用 `GazeAt` 用于会一直保持到被释放或保持时间耗尽的请求，或者 `GlanceAt` 用于短暂的一行式注视。两者都会返回一个 `GazeHandle` ，并且绝不会为 `null` 一个有效目标返回空值。

```csharp
using Convai.Modules.Gaze.Components;
using UnityEngine;

public sealed class DisplayCaseCue : MonoBehaviour
{
    [SerializeField] private Transform displayCase;
    [SerializeField] private ConvaiGazeController gaze;

    private void OnTriggerEnter(Collider other)
    {
        // 将注视保持 2 秒；如果展示柜不在轴线上，则允许全身转身。
        gaze.GazeAt(displayCase, new GazeOptions
        {
            HoldSeconds = 2f,
            Engagement = 1f,
            AllowBodyTurn = true
        });
    }
}
```

使用 `GlanceAt` 用于更短、优先级更低的注视，它绝不会让身体转身，并会自动恢复到策略目标：

```csharp
gaze.GlanceAt(displayCase, durationSeconds: 1.5f);
```

脚本化请求始终优先于自动目标。 `GazeAt` 请求优先于 `GlanceAt` 请求：任何显式的 `GazeAt` 都会抢占正在进行的瞥视。

### `GazeOptions` 字段

| 字段            | 类型      | 默认  | 用途                                                                                                            |
| ------------- | ------- | --- | ------------------------------------------------------------------------------------------------------------- |
| `优先级`         | `整数`    | `0` | 脚本化请求之间的优先级（数值更高者获胜；相同时按最近性打破平局）。                                                                             |
| `HoldSeconds` | `float` | `0` | 来自请求的保持时长（秒）。数值 `<= 0` 保持直到 `GazeHandle.Release()` 被调用。                                                       |
| `参与度`         | `float` | `0` | Engagement 覆盖值，位于 `(0, 1]`。数值 `<= 0` 使用当前对话状态的 engagement——当注视必须无论对话状态如何都要就位时，请传入显式值（例如 `1`），因为 `空闲` 默认为 `0`. |
| `允许身体转向`      | `布尔值`   | `否` | 此请求是否可以触发朝目标的全身转身。                                                                                            |

`GlanceAt` 会在内部自行构建它的 `GazeOptions` ： `HoldSeconds` 来自其 `durationSeconds` 参数（默认 `1.2f`，最小裁剪为 `0.2f`), `参与度` 固定为 `1`以及 `允许身体转向` 固定为 `否`.

### 在 Unity 中等待句柄

`GazeHandle.Settled` 在 `是` 注视对齐到目标后完成，或者 `否` 当请求在对齐前结束时完成。 `GazeHandle.Completion` 在请求结束时完成——无论是保持时间耗尽、被释放，还是目标丢失。请在 `Settled` 在后续动作之前等待，例如拾取手势这类依赖角色先明显看向目标的动作。

```csharp
using System.Threading.Tasks;
using Convai.Modules.Gaze.Components;
using UnityEngine;

public sealed class LookThenReach : MonoBehaviour
{
    public async Task LookAtAndReachAsync(ConvaiGazeController gaze, Transform target)
    {
        GazeHandle handle = gaze.GazeAt(target, new GazeOptions { Engagement = 1f, AllowBodyTurn = true });
        if (handle == null) return;

        bool aligned = await handle.Settled;
        if (!aligned)
        {
            Debug.Log($"注视 '{handle.TargetName}' 未能稳定：{handle.Outcome}。");
            return;
        }

        // 已对齐——此处可以安全地开始伸手或拾取动画。
    }
}
```

{% hint style="warning" %}
`Settled` 可以完成 `否` 用于明确未被接受的请求——参见 `GazeOutcome.HeldEyeContactInstead` 下方——而不仅仅是用于真正的失败。应当根据 `结果` 而不是只看布尔值本身，再将一个 `否` 结果视为错误。
{% endhint %}

调用 `handle.Release()` 以提前结束请求。 `释放` 可以安全地多次调用，也可在取消回调中调用。调用 `ConvaiGazeController.ReleaseAllScriptedGaze()` 可一次性结束角色上的每个脚本化请求，例如在过场动画中止时。

### `GazeOutcome` 值

| 值                       | 整数  | 含义                                                                     |
| ----------------------- | --- | ---------------------------------------------------------------------- |
| `Taken`                 | `0` | 请求处于活动状态，或者它已抵达目标。默认状态，直到另有说明。                                         |
| `被打断`                   | `1` | 请求在注视抵达前结束——被释放、过期、被更高优先级的注视取代，或者其目标已被销毁。                              |
| `HeldEyeContactInstead` | `2` | 角色刻意保持了眼神接触，瞥视被并入其中而没有被接管，因为 `LockBlocksGlances` 已开启。没有出错——角色选择了人而不是物。 |

### 眼神接触锁定如何改变脚本化请求

`AllowScriptedOverridesDuringExactFocus` 和 `LockBlocksGlances`，在 `ConvaiGazeController`，决定在眼神接触锁定（`ConversationLock` 或 `AlwaysLock` `EyeContactMode`）生效时，脚本化请求是否会被接受：

* 当 `FocusFidelity` 是 `精确`时，显式的 `GazeAt` 请求会被直接拒绝，除非 `AllowScriptedOverridesDuringExactFocus` 是 `是`。被拒绝的请求会返回一个其 `Completion` 已经完成，并且其 `Settled` 会解析为 `否`.
* 当 `FocusFidelity` 是 `社交`时，显式的 `GazeAt` 请求始终会抢占该锁。
* `GlanceAt` 请求会在 `LockBlocksGlances` 是 `是` （默认值）期间被吸收：返回的句柄会立即以 `结果` 设置为 `HeldEyeContactInstead`完成，且目光绝不会离开玩家锚点。设置 `LockBlocksGlances` 移动到 `否` 可让瞥视穿过该锁继续播放。

### 故障排查

#### 一个 `GazeAt` 请求永远不会稳定下来

**症状：** `handle.Settled` 等待并返回 `否`.

**原因：** 该请求被更高优先级的脚本化请求中断、其目标被销毁，或者 `精确` focus 拒绝了它。

**解决方法：** 检查 `handle.Outcome` 在……之后 `Settled` 的解析结果以区分 `被打断` 来自 `HeldEyeContactInstead`，并触发 `优先级` 或设置 `AllowScriptedOverridesDuringExactFocus` 如果该请求应当胜出。

**验证：** 后续动作只会在以下情况后运行 `Settled` 会解析为 `是`.

### 下一步

{% content-ref url="/pages/864133eda5776302d8f8f9afeef2de62388e08bc" %}
[视线目标与提供器](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/embodiment/gaze/targets-and-providers.md)
{% endcontent-ref %}

{% content-ref url="/pages/3e45c80fb1153e604c743a1f3a0a835d39719b0e" %}
[配置眼神接触](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/embodiment/gaze/configure-eye-contact.md)
{% endcontent-ref %}

{% content-ref url="/pages/e18fef943d7f4b642c516d5b9e2c689030154ddf" %}
[Gaze 脚本参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/embodiment/gaze/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, and the optional `goal` query parameter:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/embodiment/gaze/scripted-gaze.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.
