> 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/usage-examples.md).

# 视觉使用示例

这些示例涵盖了最常见的 Vision 集成模式。每个示例都是独立的——复制相关脚本，将其附加到相应的 GameObject 上，并在 Inspector 中配置序列化字段。

### 在安全培训中监控物体放置

一个安全培训应用，其中 Convai 角色会监控用户是否将设备放置在正确区域，并给出语音反馈。该角色使用实时场景摄像头画面来观察放置情况。

**预期结果：** 当玩家移动物体时，角色会描述其位置，并确认放置是否正确，或标记安全问题。

```csharp
using Convai.Modules.Vision;
using Convai.Runtime.Vision.Publishing;
using UnityEngine;

/// <summary>
/// 在培训序列开始时启用视觉，并在完成时禁用。
/// 将其附加到与 ConvaiVisionPublisher 相同的 GameObject 上。
/// </summary>
public class SafetyTrainingVisionController : MonoBehaviour
{
    [SerializeField] private ConvaiVisionPublisher _publisher;

    void Awake()
    {
        // 以手动模式启动，这样视觉只会在主动培训期间采集
        _publisher.SetPublishPolicy(VisionPublishPolicy.Manual);
    }

    public void BeginTrainingSequence()
    {
        _publisher.SetPublishPolicy(VisionPublishPolicy.HighResponsiveness);
        _publisher.EnablePublishing(true);
    }

    public void EndTrainingSequence()
    {
        _publisher.EnablePublishing(false);
        _publisher.SetPublishPolicy(VisionPublishPolicy.Manual);
    }
}
```

### 运行时选择摄像头设备

一个桌面入门应用，用户在会话开始前选择要使用的物理摄像头。当用户的工作站有多个摄像头（内置摄像头、USB 摄像头等）时非常有用。

**预期结果：** 下拉菜单会在 Start 时填充所有检测到的摄像头名称。选择一个摄像头名称并点击 **切换** 即可在不中断会话的情况下更换采集设备。

```csharp
using System.Collections.Generic;
using Convai.Runtime.Vision.Sources;
using TMPro;
using UnityEngine;

/// <summary>
/// 使用可用的摄像头名称填充 TMP_Dropdown，并按需切换设备。
/// 需要场景中存在 WebcamVisionFrameSource。
/// </summary>
public class WebcamSelectorUI : MonoBehaviour
{
    [SerializeField] private WebcamVisionFrameSource _webcamSource;
    [SerializeField] private TMP_Dropdown _deviceDropdown;

    private List<string> _deviceNames = new();

    async void Start()
    {
        _deviceNames = new List<string>(WebcamVisionFrameSource.GetAvailableDeviceNames());
        _deviceDropdown.ClearOptions();
        _deviceDropdown.AddOptions(_deviceNames);

        _deviceDropdown.onValueChanged.AddListener(async index =>
        {
            if (index >= 0 && index < _deviceNames.Count)
                await _webcamSource.SwitchWebcamAsync(_deviceNames[index]);
        });
    }
}
```

{% hint style="info" %}
`TMP_Dropdown` 需要 TextMeshPro 包。如果你的项目使用旧版 `UnityEngine.UI.Dropdown`，请将 `TMP_Dropdown` 其带有 `Dropdown` — `AddOptions(List<string>)` 的工作方式完全相同。
{% endhint %}

### 流式传输一个俯视安防摄像头

一个建筑导览应用，其中俯视安防摄像头监控整个平面图。发布器使用 `低开销` 策略，因为场景变化较慢，而且带宽必须留给音频。

**预期结果：** 当被询问时，角色会描述俯视视图中可见的内容——家具布局、占用情况或危险。

```csharp
using Convai.Modules.Vision;
using Convai.Runtime.Vision.Publishing;
using UnityEngine;

/// <summary>
/// 使用特定的俯视摄像头和低开销传输策略配置视觉。
/// 将其附加到 ConvaiVisionRoot GameObject。
/// </summary>
public class SecurityCameraVisionSetup : MonoBehaviour
{
    [SerializeField] private ConvaiVisionPublisher _publisher;
    [SerializeField] private CameraVisionFrameSource _frameSource;
    [SerializeField] private Camera _overheadCamera;

    void Awake()
    {
        // 将帧源指向俯视安防摄像头
        _frameSource.TargetCamera = _overheadCamera;

        // 低开销策略：5 fps，350 kbps——适用于缓慢移动的场景
        _publisher.SetPublishPolicy(VisionPublishPolicy.LowOverhead);
    }
}
```

### 在玩家注视时激活发布

持续流式传输视觉内容代价很高。此模式仅在玩家注视特定物体（例如某台机器）时激活发布，否则暂停。

**预期结果：** 只有当玩家注视物体时，角色才会响应其状态。玩家移开视线时，网络和 GPU 开销为零。

```csharp
using Convai.Modules.Vision;
using Convai.Runtime.Vision.Publishing;
using UnityEngine;

/// <summary>
/// 当玩家注视指定物体时激活视觉发布。
/// 将其附加到目标物体。ConvaiVisionPublisher 必须设置为 Manual 策略。
/// </summary>
public class LookAtVisionTrigger : MonoBehaviour
{
    [SerializeField] private ConvaiVisionPublisher _publisher;
    [SerializeField] private Camera _playerCamera;
    [SerializeField] private float _maxViewAngle = 15f;

    void Awake()
    {
        _publisher.SetPublishPolicy(VisionPublishPolicy.Manual);
    }

    void Update()
    {
        Vector3 directionToObject = (transform.position - _playerCamera.transform.position).normalized;
        float angle = Vector3.Angle(_playerCamera.transform.forward, directionToObject);
        bool isLooking = angle < _maxViewAngle;

        if (isLooking && !_publisher.IsPublishing)
            _publisher.EnablePublishing(true);
        else if (!isLooking && _publisher.IsPublishing)
            _publisher.EnablePublishing(false);
    }
}
```

### 为 WebGL 配置 Vision

在 WebGL 上，不需要帧源组件。 `ConvaiVisionPublisher` 通过以下方式自动捕获浏览器画布 `canvas.captureStream()`。将 **连接类型** 到 **视频** 以及按需设置发布策略——其余一切都会自动完成。

**预期结果：** 角色接收浏览器画布的实时画面。场景中没有帧源组件。

```csharp
using Convai.Modules.Vision;
using Convai.Runtime.Vision.Publishing;
using UnityEngine;

/// <summary>
/// WebGL 专用设置。不需要帧源——发布器使用 canvas.captureStream()。
/// 将其附加到与 ConvaiVisionPublisher 相同的 GameObject 上。
/// 在播放前将 ConvaiRoomManager.ConnectionType 设置为 Video。
/// </summary>
public class WebGLVisionSetup : MonoBehaviour
{
    [SerializeField] private ConvaiVisionPublisher _publisher;

    void Awake()
    {
        // LowOverhead 适用于 WebGL——画布捕获上限为 15 fps
        _publisher.SetPublishPolicy(VisionPublishPolicy.LowOverhead);
    }
}
```

{% hint style="danger" %}
**WebGL 需要 HTTPS。** 该 `canvas.captureStream()` 浏览器会阻止非 HTTPS 来源的 API。请在 HTTPS 主机上部署你的 WebGL 构建，然后再在生产环境中测试 Vision。 `http://localhost` 是唯一的例外。
{% endhint %}

### 下一步

{% content-ref url="/pages/86612bc613c5a299a468b71b3fb8a40e625ee1fe" %}
[排查 Vision 问题](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/vision/troubleshooting-and-diagnostics.md)
{% endcontent-ref %}

{% content-ref url="/pages/cb7758289bc48a93210bce51933fd819fd05e245" %}
[自定义帧源](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/vision/custom-frame-sources.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:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/vision/usage-examples.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
