> 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/gaze-attention/how-gaze-attention-works.md).

# 注视注意力的工作原理

了解注视追踪管道、注意力提升计时器、组件作用域目标、高亮渲染以及注意力源锁定规则。

凝视关注是一个子系统，位于 `UConvaiPlayerComponent` 它会把玩家的注视位置转换为 AI 角色的上下文焦点。启用后，它每个 Tick 都会运行，通过高亮 Actor 和光标小组件管理视觉反馈，并在可配置的停留时长后，将内容写入聊天机器人的“关注对象”槽位。

如果你还没有启用凝视关注，请先从 [凝视关注快速入门](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/gaze-attention/gaze-attention-quick-start.md)开始。本页解释该配置背后的思维模型。

### 三个核心概念

在每帧处理流程之前，请记住这三个阶段：

| 阶段        | 发生的情况                                                                           | 玩家看到的内容                                                  |
| --------- | ------------------------------------------------------------------------------- | -------------------------------------------------------- |
| **凝视检测**  | 一条线性检测（以及可选的角度回退）会找到一个可被凝视的 `UConvaiObjectComponent` 位于准星下方的对象。                 | 高亮和光标会立即激活。                                              |
| **停留提升**  | 在……之后 `GazeAttentionDelay` 在同一目标上停留若干秒后，该对象会被提升为“正在关注”。                         | 没有新的视觉变化； `OnAttentionGained` 触发，空状态名或空值仍会记录 Console 警告。 |
| **关注所有权** | 每个聊天机器人都会通过以下方式跟踪是谁设置了它的关注槽位： `AttentionSource`。凝视只能在该槽位为 `None` 或已由凝视拥有时更新该槽位。 | 角色可以发声，也可以保持沉默，具体取决于 `GazeShouldRespond`.                |

带标签的对象来自场景元数据——参见 [场景元数据的工作方式](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/scene-metadata/how-scene-metadata-works.md)。关注所有权和代词指代解析与 [注意对象与指代消解](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/character-actions/attention-and-reference-grounding.md).

### Tick 流程

每个 Tick， `UConvaiPlayerComponent` 调用 `TickGazeAttention` 当 `bEnableGazeAttention` 是 `true`。下图显示完整的决策路径；随后的编号列表会详细说明每个阶段。

```mermaid
flowchart TD
    A([TickGazeAttention]) --> B{bEnableGazeAttention?}
    B -- No --> Z([Skip])
    B -- Yes --> C[沿 GazeTraceChannel 进行线性检测\n最多到达 GazeMaxDistance]
    F --> D{有效的凝视目标？}
    F --> D{有效的凝视目标？}
    D -- Yes --> I[生成 / 更新\nAConvaiGazeHighlightActor]
    D -- No --> E{AngleTolerance > 0\n且检测未被\n非 Convai 几何体阻挡？}
    E -- Yes --> G[点积回退：\n遍历子系统池]
    E -- No --> H([本 Tick 没有凝视目标])
    G --> Q{回退目标？}
    Q -- Yes --> I
    Q -- No --> H
    I --> J[更新 UConvaiGazeCursorWidget\n状态：Active 或 Idle]
    J --> K[Tick GazeAccumulator\n或 NoGazeAccumulator]
    K --> L{GazeAccumulator >=\nGazeAttentionDelay？}
    L -- Yes --> M([提升为关注\nOnAttentionGained 触发])
    L -- No --> N{NoGazeAccumulator >=\nGazeAttentionLossDelay？}
    N -- Yes --> O([释放关注\nOnAttentionLost 触发])
    N -- No --> P([累积——状态不变])
```

1. 一条线性检测从玩家摄像机或 VR HMD 向前发射，沿着 `GazeTraceChannel` （默认 `ECC_Visibility`）最远到 `GazeMaxDistance` （默认 5000 cm）。
2. 检测结果会被测试是否命中一个可凝视的 `UConvaiObjectComponent` 位于命中的 Actor 上。只有当对象作用域为整个 Actor，或者命中的原语与该对象配置的组件作用域匹配时，才会接受该凝视目标。
3. 如果严格检测未命中有效的凝视目标，则在以下情况下会运行点积回退： `GazeAngleTolerance` 大于零，并且主检测未被非 Convai 几何体阻挡。回退会遍历每一个 `UConvaiObjectComponent` 在子系统中注册的对象，丢弃超出范围、位于摄像机后方或位于锥体半角之外的项，并选择与视线方向点积最高的那个。这避免了球形检测物理查询，并且以与距离无关的方式工作——远处对象所需的屏幕容差与近处对象相同。
4. 任何凝视目标之间的切换（进入或离开）都会触发 `OnGazeBegin` 或 `OnGazeEnd` 在玩家组件上触发，并更新光标小组件状态。
5. 两个累加器并行运行： `GazeAccumulator` 统计当前目标已保持了多长时间，而 `NoGazeAccumulator` 统计玩家已经离开任何 Convai 对象多久了。

### 关注的提升与释放

当 `GazeAccumulator` 达到 `GazeAttentionDelay` 秒（默认 1.0）后，凝视目标会被提升为“正在关注”：

* 玩家组件会调用聊天机器人组件上的一个内部方法，传入 `FConvaiObjectEntry` 目标对应的 `GazeAttentionText` 和 `GazeShouldRespond`以及
* `OnAttentionGained` 的值。这会自动处理——不需要 Blueprint 连线。
* 聊天机器人的 `AttentionSource` 属性会被写为 `EConvaiAttentionSource::Gaze`.

当 `NoGazeAccumulator` 达到 `GazeAttentionLossDelay` 秒（默认 5.0）后，并且玩家不再注视当前的关注 Actor/原语对时，该槽位会被释放：

* 玩家组件会调用聊天机器人组件上的内部方法来清空关注槽位。同样，这是自动完成的。
* `OnAttentionLost` 的值。这会自动处理——不需要 Blueprint 连线。
* 聊天机器人的 `AttentionSource` 重置为 `EConvaiAttentionSource::None`.

### 关注源锁定规则

聊天机器人会通过以下方式跟踪最后一次设置其关注槽位的是谁： `AttentionSource` (`EConvaiAttentionSource`）。 `AttentionSource` 上的属性 `UConvaiChatbotComponent` 会经历三个状态：

```mermaid
stateDiagram-v2
    [*] --> None
    None --> Gaze : TrySetObjectInAttentionFromGaze()
    Gaze --> Gaze : 新的凝视目标被提升
    Gaze --> None : TryClearObjectInAttentionFromGaze()\n或丢失计时器到期
    None --> Explicit : 从 Blueprint/C++ 调用 SetObjectInAttention()
    Gaze --> Explicit : 从 Blueprint/C++ 调用 SetObjectInAttention()
    Explicit --> None : 使用空的 FConvaiObjectEntry 调用 SetObjectInAttention()
    Explicit --> Explicit : 使用新对象调用 SetObjectInAttention()
```

| 值                   | 含义                                     |
| ------------------- | -------------------------------------- |
| `None`              | 关注槽位为空。                                |
| `Gaze`              | 该槽位上次由凝视系统设置。                          |
| `显式（Blueprint/C++）` | 该槽位上次由一次直接的 `SetObjectInAttention` 调用。 |

基于凝视的更新只有在以下情况下才会成功： `AttentionSource` 是 `None` 或 `Gaze`。直接调用 `SetObjectInAttention` 从 Blueprint 或 C++ 设置 `AttentionSource` 到 `显式`，并锁定该槽位。凝视调用在槽位被锁定时会被拒绝，拒绝时会记录一条警告，说明对象和原因。要释放显式锁，请调用 `SetObjectInAttention` 并传入空的 `FConvaiObjectEntry`.

{% hint style="warning" %}
如果某个角色的关注槽位无论玩家看向哪里都始终停留在同一个对象上，请检查是否有某个 Blueprint 图在调用 `SetObjectInAttention` ，而从未清空它。 `AttentionSource` 聊天机器人上的只读属性会显示当前由哪个系统拥有该槽位。
{% endhint %}

### 关注与动作系统

`SetObjectInAttention` 在以下情况下没有效果： `启用操作` (`bEnableActions`) 为 `false` 在聊天机器人上。只有当 `action_config` 块在会话连接时已包含——这要求启用动作。因此，凝视关注要求聊天机器人的动作系统处于激活状态。由于这个原因而不起作用的调用，或者因为目标对象尚未出现在聊天机器人的环境列表中，或未包含在连接时发送的对象中，都会记录一条警告，说明对象和具体原因——参见 [诊断来自 SetObjectInAttention 的“无效果”警告](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/gaze-attention/troubleshoot-gaze-attention.md#diagnose-a-no-effect-warning-from-setobjectinattention).

### 一次性刷新关注提示

当一次凝视提升（或一次显式 `SetObjectInAttention` 调用）成功并且 `GazeShouldRespond`/`ShouldRespond` 是 `自动` 或 `Always`，聊天机器人会生成一条一次性的临时事件，内容为 `“<observer> 正在关注 <object name>”` — `<observer>` 是对话伙伴的名字；如果未设置，则为“The user”。该提示不会持久保存在上下文中，并且每次提升只触发一次；当关注仍停留在同一对象上时不会重复。默认启用，可通过每次调用传入 `bAddAttentionEvent = false` 到 `SetObjectInAttention`。设置 `ShouldRespond`/`GazeShouldRespond` 到 `Never` 也会抑制它——槽位仍然会更新，但不会发出声音。

### 组件作用域凝视

`ObjectEntry.ObjectReference` (`EConvaiObjectReference`，Details 面板标签 **对象为**）说明了该对象 *是* 对每个读取 `FConvaiObjectEntry` ——无论是凝视、移动回退还是视觉标记皆如此。它有两个值：

* **整个 Actor** （默认）——整个 Actor 就是该对象。凝视会匹配该 Actor 的任何原语。
* **特定组件** ——某个命名子组件就是该对象。凝视只匹配该组件。将 `ObjectEntry.ComponentName` 设置为目标组件名称的一个不区分大小写的子字符串；非空 `组件名称` 在以下情况下没有效果： `对象引用` 仍然是 **整个 Actor**.

`GatherMatchingObjects` 会将 `UConvaiObjectComponent` 命中 Actor 上的实例分为两组：

| 组        | 条件                                                 | 在以下情况触发：                                                                                 |
| -------- | -------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| 整个 Actor | `对象引用` 是 `整个 Actor`，或 `对象引用` 是 `特定组件` 并传入空的 `组件名称` | 当该 Actor 没有已解析的组件作用域对象时，对该 Actor 的任何命中都会触发。如果同一 Actor 上有某个组件作用域对象匹配，则整个 Actor 对象会作为附带触发。 |
| 组件作用域    | `对象引用` 是 `特定组件` 和 `组件名称` 解析为该 Actor 上的某个组件         | 命中原语与已解析组件匹配（或附加在其上）                                                                     |

当某个组件作用域组件匹配时，同一 Actor 上的任何整个 Actor 组件也会触发（“piggyback” 规则）。如果该 Actor 已解析出组件作用域对象，但命中原语与其中任何一个都不匹配，则该次命中不会触发任何凝视对象。

**示例——一个带有两个 Convai 对象的门 Actor：**

```
BP_Door
├── ConvaiObjectComponent "Door"        → 对象类型：整个 Actor
└── ConvaiObjectComponent "DoorHandle"  → 对象类型：特定组件，组件名称："Handle"
    └── 指向该 Actor 上的 SM_Handle
```

* 玩家看向门框 → 没有凝视对象触发，因为该 Actor 有一个已解析的组件作用域对象，而命中原语与其不匹配。
* 玩家看向把手 → `ConvaiObjectComponent "DoorHandle"` 触发； `ConvaiObjectComponent "Door"` 也会触发（piggyback）。高亮 Actor 作用域限定到 `SM_Handle` 仅此而已。

`组件名称` 匹配采用不区分大小写的子字符串查找。 `GetResolvedComponent()` 每次调用都会重新验证缓存的匹配——如果缓存组件的所有者或名称不再符合过滤条件，它会自动重新扫描，因此即使 Actor 的组件树在运行时发生变化，也不需要手动刷新调用。未解析的 `组件名称` 在首次尝试解析时会记录一条警告，并且在名称解析成功之前，该组件会被排除在作用域凝视遍历之外。

{% hint style="info" %}
使用组件作用域的 `UConvaiObjectComponent` 实例，让一个复杂道具能够暴露多个独立交互点——每个点都有自己的 `名称`, `说明`、以及凝视事件——而无需复制父 Actor。
{% endhint %}

### 视觉反馈

#### 高亮 Actor

当识别出凝视目标时， `UConvaiPlayerComponent` 会生成（或复用）一个 `AConvaiGazeHighlightActor` 位于目标之上的。高亮 Actor 使用 `UMeshComponent::SetOverlayMaterial` 在 UE 5.3 及更高版本中。默认情况下，高亮 Actor 会加载 `/ConvAI/Highlights/M_ConvaiGazeOverlay`，这是插件源代码引用的一个 Fresnel 边缘轮廓材质。该 Actor 会写入 `GazeHighlightColor` 到材质的 `EmissiveColor` 和 `Color` 向量参数，然后写入 `GazeHighlightEmissiveIntensity` 到 `EmissiveIntensity` 标量参数。

在 UE 5.0–5.2 中， `SetOverlayMaterial` 在 `上不可用：`。该 Actor 会回退为一个 `DrawDebugBox` 使用以下方式在目标边界周围绘制线框： `FallbackBoxThickness` 和 `FallbackBoxPadding`.

当某个组件作用域 `UConvaiObjectComponent` 匹配时，高亮会限定到那个特定子网格，而不是该 Actor 上的每个网格。有关匹配规则，请参见 [组件作用域凝视](#component-scoped-gaze) 上文。

#### 光标小组件

一个 `UConvaiGazeCursorWidget` 在凝视跟踪激活且以下条件成立时，会被添加到视口中： `bShowGazeCursor` 是 `true`。该小组件有两种视觉状态：

* **Idle** ——凝视不在任何 Convai 对象上。使用 `凝视光标空闲颜色` （默认 alpha 为 0，完全透明）。
* **Active** ——凝视位于一个 Convai 对象上。使用 `凝视光标激活颜色` （默认白色）。

状态之间的过渡会在以下时间内插值： `凝视光标淡入时间` 和 `凝视光标淡出时间`。当 `bAlwaysShowGazeCursor` 是 `true`，即使凝视不在 Convai 对象上，光标也会保持 Active 视觉状态。

该光标是一个纯 C++ 小组件，使用 Unreal 的 `FCoreStyle::WhiteBrush`。插件不包含任何纹理资源。若要显示自定义瞄准线，请在 Blueprint 中继承 `UConvaiGazeCursorWidget` ，重写 `OnGazeStateChanged`，并将该子类分配给 `GazeCursorWidgetClass` 到玩家组件上的

### 下一步

{% content-ref url="/pages/c5d49eeda517161a96ea3016fa123bc1694b506f" %}
[注视注意力快速开始](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/gaze-attention/gaze-attention-quick-start.md)
{% endcontent-ref %}

{% content-ref url="/pages/797ae18ef94bcef2ec7816f079c7a35fb212a26c" %}
[注视注意力参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/gaze-attention/gaze-attention-reference.md)
{% endcontent-ref %}

{% content-ref url="/pages/2f301cf695f654f0b6dc66672ff9462854021237" %}
[注视注意力使用示例](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/gaze-attention/gaze-attention-usage-examples.md)
{% endcontent-ref %}

{% content-ref url="/pages/ca4f4235151ab1fee69bb58487611f1c6ec30cc6" %}
[排查凝视注意力问题](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/gaze-attention/troubleshoot-gaze-attention.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/gaze-attention/how-gaze-attention-works.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.
