> 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/vision/troubleshooting-and-diagnostics.md).

# 排查视觉问题

请从上到下阅读本页。大多数 Vision 失败属于四类之一：连接配置错误、帧源失败、平台特定限制，或 WebGL 来源策略。

### 快速检查清单

在深入具体问题之前，请按顺序核对以下五项：

{% stepper %}
{% step %}

#### 确认 Connection Type 为 Video

选择 `ConvaiRoomManager` 在 Hierarchy 中。确认 **Connection Type** 已设置为 **Video**. `ConvaiVisionPublisher` 当 Connection Type 为时保持完全空闲 `音频` ——它会记录一条消息并返回，不会报错。
{% endstep %}

{% step %}

#### 确认房间已连接

`ConvaiVisionPublisher` 在房间连接之前不会发布。请在 Console 中检查 `[ConvaiRoomManager]` 连接日志。确认 `ConvaiManager.ActiveManager` 在运行时不为 null。
{% endstep %}

{% step %}

#### 确认存在帧源

在原生平台（非 WebGL）上， `ConvaiVisionPublisher` 需要一个帧源。确认 `CameraVisionFrameSource`, `WebcamVisionFrameSource`，或者一个自定义的 `IVisionFrameSource` 位于同一个 GameObject 或其子对象上。请在 Console 中检查：

```
[ConvaiVisionPublisher] 未找到 IVisionFrameSource。
```

{% endstep %}

{% step %}

#### 确认帧源处于 Ready 状态

在运行时于 Inspector 中打开帧源组件。确认 `状态` 是 `就绪`。如果它是 `失败`，请检查 `错误类型` 和 `状态消息` 在 Inspector 或 Console 中。
{% endstep %}

{% step %}

#### 将 VisionDebugPreview 添加到

添加 `VisionDebugPreview` 任意场景 GameObject 上。按下 Play。若覆盖层显示实时图像并且 `FPS > 0`，说明视频流已到达发布器。如果覆盖层为空白或 FPS 一直为零，则帧源没有生成帧——继续查看 [帧源问题](#frame-source-issues) 下方。
{% endstep %}
{% endstepper %}

### 常见问题

| 症状                        | 可能原因                                                   | 修复                                                                                                                                        | 验证                                                                                                                                                                                                    |
| ------------------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `IsPublishing` 保持 `false` | Connection Type 为 `音频`                                 | 将 **Connection Type** 设置为 **Video** 于 `ConvaiRoomManager`.                                                                                | 确认 `IsPublishing` 变为 `true` 在将 Connection Type 切换为 Video 并重新连接后。                                                                                                                                      |
| `IsPublishing` 保持 `false` | 房间未连接                                                  | 等待连接，或检查 API key / 网络。                                                                                                                    | 请在 Console 中检查 `[ConvaiRoomManager]` 连接日志，并确认 `ConvaiManager.ActiveManager` 不是 `null`.                                                                                                                |
| `IsPublishing` 保持 `false` | 未找到帧源                                                  | 添加 `CameraVisionFrameSource` 到同一个或子级 GameObject。                                                                                          | 确认 Console 不再记录 `[ConvaiVisionPublisher] 未找到 IVisionFrameSource。`                                                                                                                                     |
| 调试覆盖层为空白，FPS = 0          | 帧源中的 `失败` state                                        | 检查 `错误类型` ——参见 [帧源问题](#frame-source-issues).                                                                                              | 确认 `状态` 帧源组件上的切换离开 `失败` 在应用下方对应修复后。                                                                                                                                                                   |
| 视频流为黑屏                    | 错误的 `CameraCaptureMode` 用于渲染管线                         | 参见 [黑屏视频流](#black-feed).                                                                                                                  | 确认 `VisionDebugPreview` 在切换模式后，覆盖层显示非黑色图像。                                                                                                                                                            |
| `SrpNative` 已选择           | 未实现的后端                                                 | `CameraVisionFrameSource` 进入 `失败` 会立即——请使用 `ExplicitRenderCompatibility` 在 SRP/URP 上。                                                     | 确认 `状态` 不再报告 `失败` ，参数为 `ErrorKind = UnsupportedPlatform`.                                                                                                                                             |
| 摄像头未打开                    | 权限被拒绝（Android / iOS）                                   | 声明 `android.permission.CAMERA` 到 manifest 中；添加 `NSCameraUsageDescription` 到 Info.plist 中。                                                 | 确认 `状态` 不再报告 `PermissionDenied` 并且在授予权限对话框后，摄像头预览会出现。                                                                                                                                                 |
| Quest 视频流未启动              | 缺少 manifest 权限                                         | 同时声明这两个权限 `horizonos.permission.HEADSET_CAMERA` 和 `android.permission.CAMERA`.                                                            | 确认穿透采集已启动，并且 `状态` 到达 `就绪` 在声明这两项后重新部署。                                                                                                                                                                |
| Quest 视频流未启动              | 硬件错误                                                   | `QuestVisionFrameSource` 需要 Quest 3 或 3S。Quest 2 和 Quest Pro 不受支持。                                                                        | 确认目标设备为 Quest 3 或 3S—— `状态` 无法到达 `就绪` 在不受支持的硬件上，无论权限如何。                                                                                                                                               |
| WebGL 视频流未发布              | 非 HTTPS 源                                              | 部署到 HTTPS。 `http://localhost` 是唯一的例外。                                                                                                     | 确认部署后的 URL 使用 `https://` （或者是 `http://localhost`).                                                                                                                                                    |
| WebGL 视频流未发布              | 已分配帧源                                                  | 在 WebGL 上会忽略帧源——请移除或留空；发布器使用 `canvas.captureStream()`.                                                                                    | 确认 `IsPublishing` 变为 `true` 在移除帧源引用后。                                                                                                                                                                 |
| WebGL 上的调试覆盖层为空白          | 预期如此——没有 RenderTexture                                 | `VisionDebugPreview` 在 WebGL 上没有可显示的纹理。通过 `IsPublishing` 来代替。                                                                             | 确认 `IsPublishing` 是 `true` 进行验证，即使覆盖层仍然为空白。                                                                                                                                                           |
| 采样窗口对帧选择没有影响              | A **采样窗口** 条目已设置 **数量** 已设置，但 **间隔毫秒** 仍保持为 `0` （或者相反） | 将两者都设置为 **数量** 和 **间隔毫秒** 为以下内容下的每个条目设置为非零值： **采样窗口** 于 `ConvaiRoomManager` （或 `ConvaiRoomManagerProfile` 资源）。请删除未使用的条目，不要让其中一个字段保持为 `0`. | 确认在 Inspector 中两个字段都显示非零值。被丢弃的窗口不会在 Console 中记录警告——SDK 只会在窗口数量超过 **每回合帧数** 预算——因此没有日志并不能证明该窗口已发送。                                                                                                     |
| Respond 模式变更没有可见效果        | `UpdateRespondMode` 已返回 `false`，或者后端拒绝了请求              | 检查 `bool` 的返回值 `UpdateRespondMode` 再假定它已生效；仅在以下状态下调用它： `IsConnected` 是 `true`。订阅 `RespondModeUpdateResultReceived` 并检查 `状态` 和 `消息`.       | 确认 `RespondModeUpdateResultReceived.Status` 是 `"success"` 和 `模态` / `模式` 是否与请求的通道和模式匹配。参见 [Vision 脚本 API](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/vision/scripting-api.md) 事件订阅模式。 |

### 帧源问题

#### 黑屏视频流

在上出现黑屏视频流（覆盖层可见但所有像素均为黑色） `CameraVisionFrameSource` 表示当前活动渲染管线使用了错误的采集后端。

| 渲染管线                       | 推荐模式                                      | 原因                                                     |
| -------------------------- | ----------------------------------------- | ------------------------------------------------------ |
| 内置渲染管线                     | `Auto` （使用 `BuiltInHooks`)                | `Camera.onPreRender` / `Camera.onPostRender` 钩子可以正常工作。 |
| URP / SRP                  | `Auto` （使用 `ExplicitRenderCompatibility`) | 显式 `Camera.Render()` 在 `LateUpdate` ——适用于所有 SRP 版本。    |
| 在 Auto 下出现黑屏视频流的 URP / SRP | `ExplicitRenderCompatibility`             | 强制使用显式渲染路径；可解决自定义 SRP 配置中的黑屏视频流。                       |

{% hint style="danger" %}
不要选择 `SrpNative`。此 SDK 构建中未实现它。选择它会导致 `CameraVisionFrameSource` 进入 `失败` 状态，并立即出现 `ErrorKind = UnsupportedPlatform`.
{% endhint %}

#### 未分配摄像机

如果 **目标摄像机** 为空，且场景中没有任何摄像机标记为 **MainCamera**, `CameraVisionFrameSource` 进入 `失败` 启动时的状态：

```
ErrorKind = InvalidConfiguration
StatusMessage = "未分配摄像机且 Camera.main 为 null"
```

修复：将摄像机分配给 **目标摄像机** 字段，或者给一个摄像机添加 **MainCamera**.

#### 摄像头权限被拒绝

在 Android 和 iOS 上， `WebcamVisionFrameSource` 会在以下时请求摄像头权限： `StartCapture()`。如果用户拒绝：

```
State = Failed
ErrorKind = PermissionDenied
```

**Android：** 验证 `AndroidManifest.xml` 声明了 `android.permission.CAMERA`.\
**iOS：** 验证 `Info.plist` 包含 `NSCameraUsageDescription` 并带有非空字符串。

如果用户之前已拒绝权限，系统不会再次显示对话框。请引导用户前往设备的“设置”应用重新启用。

#### Quest 穿透未启动

`QuestVisionFrameSource` 需要同时具备 manifest 权限和正确的硬件。

必需的 manifest 条目：

```xml
<uses-permission android:name="horizonos.permission.HEADSET_CAMERA" />
<uses-permission android:name="android.permission.CAMERA" />
```

如果没有这两个声明，穿透采集会静默失败，且帧源会进入 `失败` 状态。设备不会显示权限对话框——而是直接拒绝访问。

支持的硬件：仅限 Meta Quest 3 和 Quest 3S。Quest 2 和 Quest Pro 不提供 `PassthroughCameraAccess`.

### 决策树

```mermaid
flowchart TD
    A[IsPublishing = false？] --> B{Connection Type = Video？}
    B -- 否 --> B1[在 ConvaiRoomManager 上将 Connection Type 设置为 Video]
    B -- 是 --> C{房间已连接？}
    C -- 否 --> C1[检查 API key、网络以及 Console 中的连接错误]
    C -- 是 --> D{已找到帧源？}
    D -- 否 --> D1[将 CameraVisionFrameSource 添加到同一或子级 GameObject]
    D -- 是 --> E{帧源 State = Ready？}
    E -- 否 --> F{ErrorKind？}
    F -- InvalidConfiguration --> F1[分配 Target Camera 或标记 MainCamera]
    F -- PermissionDenied --> F2[添加 manifest 权限；引导用户到 Settings]
    F -- UnsupportedPlatform --> F3[检查是否未选择 SrpNative；Quest 源需要 Quest 3/3S]
    F -- DeviceUnavailable --> F4[检查摄像头设备名称；验证硬件已连接]
    E -- 是 --> G{视频流黑屏？}
    G -- 是 --> G1[将 Camera Capture Mode 切换为 ExplicitRenderCompatibility]
    G -- 否 --> H[IsPublishing = true —— 检查 VisionDebugPreview 覆盖层]
```

### 启用帧健康探针

对于持续为空白或黑色、且不会产生一个 `失败` 状态的帧，请在 `CameraVisionFrameSource`:

1. 选择 **ConvaiVisionRoot** GameObject 上启用诊断探针。
2. 开启 `CameraVisionFrameSource`，启用 **启用诊断帧健康探针**.
3. 按下 Play 并观察 Console。

该探针会每帧执行一次同步的 GPU 到 CPU 像素回读并记录结果。这可以确认 `RenderTexture` 是否包含图像数据，或确实为空白。

{% hint style="warning" %}
禁用 **启用诊断帧健康探针** 在发布前请勿启用。它会每帧执行一次同步 GPU 回读，这会导致 GPU 管线停顿并显著降低帧率。
{% endhint %}

### 日志

所有 Vision 日志消息都使用 `LogCategory.Vision`。将日志级别设置为 `详细` 在 **Tools → Convai → Configuration → Logging** 即可查看所有状态转换、帧源发现和发布事件。

| 前缀                           | 组件                |
| ---------------------------- | ----------------- |
| `[ConvaiVisionPublisher]`    | 发布器生命周期、帧源发现、策略更改 |
| `[VisionPublishCoordinator]` | 跟踪打开/关闭、帧路由       |
| `[CameraVisionFrameSource]`  | 摄像机采集后端选择、状态转换    |
| `[WebcamVisionFrameSource]`  | 设备打开、权限请求、状态转换    |
| `[QuestVisionFrameSource]`   | 穿透 API 绑定、状态转换    |
| `[VisionDebugPreview]`       | 帧源发现、回退切换         |

### 下一步

如果此处未涵盖该问题，请订阅 `视觉捕获已停止` 和 `视频轨道已取消发布` 并记录 `原因` 和 `错误消息` 字段。参见 [Vision 脚本 API](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/vision/scripting-api.md) 事件订阅模式。


---

# 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/vision/troubleshooting-and-diagnostics.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.
