> 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/vision/custom-vision-components.md).

# 自定义视觉组件

本页面适用于高级 C++ 项目。大多数团队应使用内置的 **Environment Webcam** 来自 [视觉快速入门](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/vision/vision-quick-start.md).

当你的项目需要不同的图像源时，创建一个实现以下接口的自定义组件 `IConvaiVisionInterface` 这样 `UConvaiChatbotComponent` 可以发现或注册它。当继承自 `UConvaiWebcamBase`，请继承 `USceneComponent`.

### 先决条件

* 启用了 Convai 插件的 C++ Unreal 项目。
* `ConvaiVisionBase` 添加到你的模块的 `PublicDependencyModuleNames` 在 `Build.cs`.
* 一个可工作的聊天机器人设置，来自 [添加您的第一个 Convai 角色](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/getting-started/add-your-first-convai-character.md).

### 何时实现自定义组件

**Environment Webcam** 从一个 `USceneCaptureComponent2D` 到一个 `UTextureRenderTarget2D`。将其用于标准的引擎内场景捕获。

在以下情况下适合使用自定义组件：

* 你的源是一个外部 SDK，它在 Unreal 的纹理管线之外生成原始像素数据。
* 你的管线已经生成图像字节，并且你需要完全控制 RGBA 转换。
* 你需要将程序化或生成的图像流注入对话中。
* 你正在封装一个非组件后端，并且需要为聊天机器人提供一个组件外观。

### 选择你的基类

| 选项                                                | 适用场景                                                                                  |
| ------------------------------------------------- | ------------------------------------------------------------------------------------- |
| 继承自 `UConvaiWebcamBase`                           | 你希望可在 Blueprint 中访问的 **Start**, **Stop**, **获取状态**, **Set Max FPS**、错误获取器以及 **帧就绪时**. |
| 实现 `IConvaiVisionInterface` 直接在 `UActorComponent` | 你需要一个不继承以下类的组件 `UConvaiWebcamBase`，但仍通过 **设置 Vision 组件** 或 Actor 发现机制进行注册。            |

对于大多数自定义源，请继承自 `UConvaiWebcamBase`。重写你的源所需的捕获方法，并让基类处理状态、FPS 存储和错误报告。

`bAutoStartVision` 仅存在于 `UEnvironmentWebcam`。自定义子类必须调用 **Start** 来自 `BeginPlay` 或暴露它们自己的自动启动属性。

### 接口契约

下表列出了以下接口上的纯虚方法： `IConvaiVisionInterface` 在 `VisionInterface.h`。当继承自 `UConvaiWebcamBase`，请重写 `CanStart`, `CaptureRaw`，并且可选地重写 `GetImageTexture` 或 `CaptureCompressed`.

| 方法                                       | 用途                   | 说明                                          |
| ---------------------------------------- | -------------------- | ------------------------------------------- |
| `void Start()`                           | 开始捕获。                | 随附的基类将状态设置为 `正在采集`.                         |
| `void Stop()`                            | 结束捕获。                | 随附的基类将状态设置为 `已停止`.                          |
| `EVisionState GetState() const`          | 返回当前生命周期状态。          | 聊天机器人每个 tick 调用，用于控制上传。                     |
| `void SetMaxFPS(int MaxFPS)`             | 设置最大捕获 FPS。          | `UConvaiWebcamBase` 拒绝以下值 `<= 0`。默认值为 `15`. |
| `int GetMaxFPS() const`                  | 返回当前最大 FPS。          | 聊天机器人上传会将实际发送速率限制为 `1`–`60`.                |
| `bool IsCompressedDataAvailable() const` | 返回 `true` 如果预压缩帧已就绪。 | 接口契约的一部分。随附的聊天机器人路径使用 `CaptureRaw()`.       |
| `bool GetCompressedData(...)`            | 检索预压缩帧。              | 对自定义集成而言可选。                                 |
| `bool CaptureCompressed(...)`            | 按需捕获并压缩。             | 可选。随附的聊天机器人路径使用 `CaptureRaw()`.             |
| `bool CaptureRaw(...)`                   | 捕获原始 RGBA 帧。         | 聊天机器人上传所需。填充按行优先排列的 RGBA 字节并返回 `true` 成功时返回 |
| `UTexture* GetImageTexture(...)`         | 返回当前帧纹理。             | 设置 `TextureSourceType` 以匹配你的纹理类型。           |
| `FString GetLastErrorMessage() const`    | 返回最后一个可读错误。          | 如果未发生错误，则返回空字符串。                            |
| `int GetLastErrorCode() const`           | 返回最后一个数值错误代码。        | `UConvaiWebcamBase` 将此值初始化为 `-1`.           |

### 从 UConvaiWebcamBase 实现

`UConvaiWebcamBase` 在以下文件中声明： `ConvaiWebcamBase.h` 在 `ConvaiVisionBase` 模块。

{% stepper %}
{% step %}

#### 声明该类

创建一个 `USceneComponent` 继承自 `UConvaiWebcamBase`。将其标记为 `BlueprintSpawnableComponent` 如果你希望它出现在组件选择器中。

```cpp
// MyCustomVisionComponent.h
// 伪代码：将 FMyImageSource 替换为你自己的图像源类型。
#pragma once

#include "ConvaiWebcamBase.h"
#include "MyCustomVisionComponent.generated.h"

UCLASS(ClassGroup=(Convai), meta=(BlueprintSpawnableComponent))
class MYPROJECT_API UMyCustomVisionComponent : public UConvaiWebcamBase
{
    GENERATED_BODY()

protected:
    virtual bool CanStart() override;
    virtual bool CaptureRaw(int& Width, int& Height, TArray<uint8>& Data) override;

private:
    TSharedPtr<FMyImageSource> MyImageSource;
};
```

{% endstep %}

{% step %}

#### 重写 CanStart

`CanStart` 在基类切换到以下状态之前运行 `正在采集`。返回 `true` 仅当你的源已初始化时。调用 `SetErrorCodeAndMessage` 当源未就绪时，这样 **获取最后错误消息** 是位于 **获取最后错误代码** 会在 Blueprint 中返回有用的值。

```cpp
// MyCustomVisionComponent.cpp
// 伪代码
bool UMyCustomVisionComponent::CanStart()
{
    if (!MyImageSource.IsValid())
    {
        SetErrorCodeAndMessage(1, TEXT("图像源尚未初始化。"), /*bPrintToLog=*/true);
        return false;
    }
    return true;
}
```

{% endstep %}

{% step %}

#### 重写 CaptureRaw

`CaptureRaw` 由聊天机器人上传路径调用。将 `宽度`, `高度`，以及 `Data` 填充为按行优先排列的 RGBA 字节。返回 `true` 成功时返回

```cpp
// 伪代码
bool UMyCustomVisionComponent::CaptureRaw(int& Width, int& Height, TArray<uint8>& Data)
{
    if (!MyImageSource.IsValid())
        return false;

    MyImageSource->GetRGBAFrame(Width, Height, Data);
    return Data.Num() > 0;
}
```

{% endstep %}
{% endstepper %}

### 将该组件注册到聊天机器人

将该组件添加到相同的 `Actor` 作为 `UConvaiChatbotComponent`.

* 当仅有一个视觉组件存在于该处时， `Actor`在……期间发现 `BeginPlay` 就足够了。
* 当存在多个视觉组件时，请调用 **设置 Vision 组件** 在 `BeginPlay` 并传入你想使用的组件。
* 调用 **Start** 来自 `BeginPlay`，或者在自定义类上添加你自己的自动启动属性。

### 下一步

{% content-ref url="/pages/ec5b9bfb145ddc8145050976e8e8db28d33fc076" %}
[视觉蓝图参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/vision/vision-blueprint-reference.md)
{% endcontent-ref %}

{% content-ref url="/pages/a5aa237a7b13fb2c8d46ff004c1de14a2c4cda2a" %}
[视觉帧来源](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/vision/vision-frame-sources.md)
{% endcontent-ref %}

{% content-ref url="/pages/63feddf4b54afd4fe7308827bee6b2f213dde1b6" %}
[视觉的工作方式](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/vision/how-vision-works.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-unreal-engine-plugin/features/vision/custom-vision-components.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.
