> 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).

# 自定义视觉组件

为需要向 Convai chatbot 提供场景帧的自定义 Unreal 图像管道实现一个 C++ 帧源组件。

本页面适用于高级 C++ 项目。大多数团队应使用内置的 **环境摄像头** 来自 [Vision 快速入门](/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).

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

**环境摄像头** 从 `USceneCaptureComponent2D` 渲染到 `UTextureRenderTarget2D`。用于标准的引擎内场景捕获。

当出现以下情况时，自定义组件是合适的：

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

### 选择你的基类

| 选项                                                | 何时使用                                                                            |
| ------------------------------------------------- | ------------------------------------------------------------------------------- |
| 派生自 `UConvaiWebcamBase`                           | 你希望具有 Blueprint 可访问的 **开始**, **停止**, **获取状态**, **设置最大 FPS**、错误获取器，以及 **在帧就绪时**. |
| 实现 `IConvaiVisionInterface` 直接在 `UActorComponent` | 你需要一个不继承 `UConvaiWebcamBase`的组件，但仍通过 **设置视觉组件** 或 Actor 发现进行注册。                 |

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

`bAutoStartVision` 仅存在于 `UEnvironmentWebcam`。自定义子类必须调用 **开始** 来自 `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` ，这样 **Get Last Error Message** 和 **Get Last Error Code** 才能在 Blueprint 中返回有用的值。

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

{% endstep %}

{% step %}

#### 重写 CaptureRaw

`CaptureRaw` 由聊天机器人上传路径调用。填充 `Width`, `高度`，以及 `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` current `UConvaiChatbotComponent`.

* 当场景中只存在一个视觉组件时， `Actor`，在 `BeginPlay` 期间的发现就足够了。
* 当存在多个视觉组件时，调用 **设置视觉组件** 在 `BeginPlay` 并传入你想使用的组件。
* 调用 **开始** 来自 `BeginPlay`，或者在自定义类上添加你自己的自动启动属性。

### 下一步

{% content-ref url="/pages/ec5b9bfb145ddc8145050976e8e8db28d33fc076" %}
[视觉 Blueprint 参考](/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 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/vision/custom-vision-components.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.
