【4-插件开发】系统性全面的讲解游戏开发如何开发o3de插件,以及列出详细的步骤和分析和包含内容和要点和案例和规格

下午2:26

下面是一份系统性、全面的 O3DE(Open 3D Engine)插件开发指南,覆盖概念、体系结构、准备工作、详细步骤、示例、关键要点、常见问题、测试与发布、版本兼容与规范建议等。内容以“从零到可用”的路径组织,既适合入门,也可作为实施清单与参考。


一、基础认知与术语对齐

  • O3DE 插件的本质
    • O3DE 使用 C++ 组件化架构,核心扩展单元通常称为 Gem。Gem 可包含引擎扩展(反射类、系统组件、编辑器插件)、资源、脚本、UI、工具链等。Gem 既可在运行时扩展游戏功能,也可在编辑器中扩展工具。
    • 除 Gem 外,常见扩展形态还有 Python 工具脚本(编辑器自动化/命令)、Prefab/Asset Pipeline 扩展、Project Template、External Submodule 等。
  • 插件分类与适用场景
    • Runtime 功能 Gem:提供游戏运行时功能(系统组件、模块、内存分配器、网络/物理/AI 等)。
    • Editor 扩展 Gem:在 O3DE Editor 中新增面板、菜单、工具栏、操作命令、资产导入器、属性编辑器自定义控件。
    • Asset Pipeline 扩展:如 Scene Processing Rules、Builder,扩展资源导入转换流程。
    • Script 扩展:Ebus/BehaviorContext 暴露给 Lua/Python/Script Canvas。
    • Integration/Bridge:与第三方 SDK/服务对接(广告、分析、平台、渲染后端等)。
  • 关键概念
    • Gems.json:描述 Gem 的元数据(名称、UUID、版本、依赖、平台、可选特性)。
    • Module/Component:C++ 模块定义(AZ::Module),系统组件(AZ::Component)作为服务单元;编辑器组件常派生 EditorComponent。
    • Reflection:SerializeContext、BehaviorContext、EditContext,用于序列化、脚本绑定和编辑器 UI。
    • EBus:解耦通信总线。可定义 Request/Notification/Handler。
    • Build/Pack:基于 CMake 和 PAL(Platform Abstraction Layer)进行多平台编译与条件编译。
    • Project 与 Engine 绑定:通过 o3de CLI 将 Gem 关联到工程或全局引擎注册。


二、准备工作与环境搭建

  • 系统与依赖
    • 支持平台:Windows(VS 2019/2022 + CMake + Ninja)、Linux(Clang/GCC + CMake + Ninja)。安装 Python 3.7+(O3DE 自带)、CMake(建议与 O3DE 版本对应),Git。
    • 获取源代码:克隆 O3DE 源码或下载 SDK。建议通过源代码构建以便调试引擎层。
  • 安装与编译
    • 配置引擎:
      • Windows: cmake -B build/windows -S . -G "Ninja Multi-Config" -DLY_VERSION_ENGINE_NAME=O3DE
      • Linux: cmake -B build/linux -S . -G Ninja
    • 首次构建 Editor 和 Project Manager 以确认环境正常。
    • 可选:注册引擎与项目
      • scripts/o3de.sh/o3de.bat register --this-engine
      • o3de.exe/o3de.py 创建或导入项目
  • 工具链
    • IDE:Visual Studio、VS Code、CLion。安装 C++20 支持。
    • Python:用于编辑器自动化、生成脚本、Asset Processor 扩展。
    • 调试:VS 调试器 / lldb / gdb;RenderDoc(渲染)、RHI/RPI 控制台;Asset Processor 面板。


三、总体开发流程(从零开始)

  1. 规划插件类型与边界
    • 明确插件是 Runtime 功能、Editor 工具、资源导入器还是混合。
    • 列出外部依赖、需要暴露的 API(EBus/Behavior)、跨平台支持范围。
  2. 创建 Gem 骨架
    • 使用 CLI:
      • Windows: scripts/o3de.bat create-gem -g MyAwesomeGem
      • Linux: scripts/o3de.sh create-gem -g MyAwesomeGem
    • 选择模板(默认、Tool、AssetBuilder 等);生成目录结构:
      • Gems/MyAwesomeGem/gem.json
      • Code/Include, Code/Source
      • Assets/, Registry/, Tools/, Scripts/ 等
  3. 配置 gem.json
    • 关键字段:
      • "gem_name", "display_name", "uuid", "version", "summary", "license", "origin"
      • "dependencies": 依赖其他 Gems
      • "link_type": "dynamic"|"static"
      • "requirements": 平台/规格限制
      • "user_tags": ["Editor", "Runtime", "AssetBuilder"]
    • 示例片段:
      • "dependencies": [{ "uuid": "xxxxxxxx-xxxx-....", "version_constraints": ">=1.0.0" }]
  4. CMake 集成
    • CMakeLists.txt 中:
      • ly_add_target(NAME MyAwesomeGem.Static NAMESPACE Gem TARGET_FILES_CXX ...)
      • target_link_libraries(... PRIVATE AZ::AzCore AZ::AzFramework ...)
      • 通过 PAL 宏控制平台:ly_set_target_properties(TARGET MyAwesomeGem.Static WINDOWS TRUE LINUX TRUE)
    • 若含编辑器模块,添加 MyAwesomeGem.Editor 模块与 BUILD_DEPENDENCIES。
  5. 模块与系统组件
    • 定义 Module:
      • class MyAwesomeGemModule : public AZ::Module { AZ_MODULE_CLASS(...); }
      • 提供 GetRequiredSystemComponents() 返回系统组件类型 ID。
    • 定义 SystemComponent:
      • 继承 AZ::Component,重写 Activate/Deactivate,提供服务声明:GetProvidedServices/GetRequiredServices。
      • 在 Reflect 中注册数据结构、EBus、脚本暴露。
  6. 编辑器扩展(可选)
    • 定义 Editor 系统组件和/或 Editor 组件,注册到编辑器模块。
    • 集成 Qt 面板:
      • 使用 AzToolsFramework、QDockWidget;通过 EditorMainWindow 添加菜单和面板。
    • EditContext:定义属性、UI 控件(滑条、下拉、多选、行编辑、按钮)。
  7. EBus 和脚本绑定
    • 定义 Request/Notification Bus:
      • struct MyRequests : AZ::EBusTraits { virtual void DoThing(...) = 0; };
      • using MyRequestBus = AZ::EBus;
    • BehaviorContext 暴露:
      • bc->Class("MyService")
        ->Method("DoThing", &MyService::DoThing);
    • Script Canvas:在 BehaviorContext 注册后自动可见。
  8. 资源与资产管线(可选)
    • 自定义 AssetBuilder:
      • 继承 AssetBuilderSDK::AssetBuilderCommandBus::Handler
      • 注册 patterns 与 JobDescriptor
      • 处理 CreateJobs/ProcessJob
    • SceneAPI 规则与处理器:对 DCC 资源(FBX/GLTF)导入规则扩展。
  9. 集成到项目
    • 通过 Project Manager 或 CLI:
      • o3de.py/o3de.exe register -gp Gems/MyAwesomeGem
      • o3de.py enable-gem -gn MyAwesomeGem -pp
    • 在项目的 CMake 生成构建,编译 Editor/Launcher。
  10. 调试与验证
    • 启动 O3DE Editor,检查 Gem 是否启用。
    • 查看 Console 与 Asset Processor 日志。
    • 使用 unit tests、automation tests,验证组件生命周期。


四、目录结构与文件清单(建议)

  • gem.json:元数据/依赖/平台信息
  • Code/
    • Include/MyAwesomeGem/... 头文件(公共 API)
    • Source/
      • Module.cpp / SystemComponent.cpp
      • EditorModule.cpp / EditorSystemComponent.cpp(若需要)
      • Ebuses.h / Services.h
      • Builders/(资产构建器)
      • Tests/(单元测试)
  • Assets/(默认资源、预制体、图标)
  • Registry/(默认设置、编辑器布局、注册表片段)
  • Tools/(命令行工具或 Python 脚本)
  • Scripts/(Python 自动化、编辑器命令)
  • CMakeLists.txt(目标、依赖、宏)


五、最小可用示例(Runtime Gem)

  • 目标:实现一个简单的服务,提供“打印问候”和“加法”功能,暴露到 BehaviorContext,供 Lua/Python/Script Canvas 调用。

核心代码结构:

  1. gem.json 关键字段示例
  • "gem_name": "HelloGem"
  • "uuid": "a1b2c3d4-0000-1111-2222-333344445555"
  • "version": "1.0.0"
  • "display_name": "Hello Gem"
  • "summary": "Simple example gem"
  • "user_tags": ["Runtime"]
  • "dependencies": []
  • "link_type": "dynamic"
  • "platforms": ["Windows", "Linux"]
  1. Module 与 SystemComponent 框架

// HelloGemModule.cpp
#include <AzCore/Module/Module.h>
#include <HelloGemSystemComponent.h>

namespace HelloGem
{
class HelloGemModule final
: public AZ::Module
{
public:
AZ_RTTI(HelloGemModule, "{F4A8D1A4-7F2B-4E2E-9C7E-6F2F8C0F0ABC}", AZ::Module);
AZ_CLASS_ALLOCATOR(HelloGemModule, AZ::SystemAllocator);

    HelloGemModule()

    {

        m_descriptors.insert(m_descriptors.end(), {

            HelloGemSystemComponent::CreateDescriptor()

        });

    }

    AZ::ComponentTypeList GetRequiredSystemComponents() const override

    {

        return AZ::ComponentTypeList{

            azrtti_typeid<HelloGemSystemComponent>()

        };

    }

};

}

AZ_DECLARE_MODULE_CLASS(Gem_HelloGem, HelloGem::HelloGemModule)

// HelloGemSystemComponent.h
#pragma once
#include <AzCore/Component/Component.h>

namespace HelloGem
{
class HelloGemSystemComponent
: public AZ::Component
{
public:
AZ_COMPONENT(HelloGemSystemComponent, "{9A2B5A1C-5D9F-4C27-8B18-1E1C8C9A7A22}");

    static void Reflect(AZ::ReflectContext* context);

    static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);

    static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);

    static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);

    static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);

    void Activate() override;

    void Deactivate() override;

    // Public API (也可通过 EBus 暴露)

    int Add(int a, int b) const;

};

}

// HelloGemSystemComponent.cpp
#include "HelloGemSystemComponent.h"
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Console/IConsole.h>

namespace HelloGem
{
void HelloGemSystemComponent::Reflect(AZ::ReflectContext* context)
{
if (auto sc = azrtti_castAZ::SerializeContext*(context))
{
sc->Class<HelloGemSystemComponent, AZ::Component>()
->Version(1);
if (auto ec = sc->GetEditContext())
{
ec->Class("HelloGem System", "Demo system component")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "HelloGem")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("System"));
}
}
if (auto bc = azrtti_castAZ::BehaviorContext*(context))
{
bc->Class("HelloGemSystem")
->Method("Add", &HelloGemSystemComponent::Add)
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common);
}
}

void HelloGemSystemComponent::GetProvidedServices(DependencyArrayType& provided)

{

    provided.push_back(AZ_CRC_CE("HelloGemService"));

}

void HelloGemSystemComponent::GetIncompatibleServices(DependencyArrayType& incompatible)

{

    incompatible.push_back(AZ_CRC_CE("HelloGemService"));

}

void HelloGemSystemComponent::GetRequiredServices(DependencyArrayType&) {}

void HelloGemSystemComponent::GetDependentServices(DependencyArrayType&) {}

void HelloGemSystemComponent::Activate()

{

    AZ_Printf("HelloGem", "HelloGemSystemComponent Activated\n");

}

void HelloGemSystemComponent::Deactivate()

{

    AZ_Printf("HelloGem", "HelloGemSystemComponent Deactivated\n");

}

int HelloGemSystemComponent::Add(int a, int b) const

{

    return a + b;

}

}

  1. CMakeLists.txt 关键片段

ly_add_target(
NAME Gem.HelloGem STATIC
NAMESPACE Gem
FILES_CMAKE
hello_gem_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
.
BUILD_DEPENDENCIES
PRIVATE
AZ::AzCore
AZ::AzFramework
)

ly_add_target(
NAME Gem.HelloGem.Standalone MODULE
NAMESPACE Gem
OUTPUT_NAME Gem.HelloGem
BUILD_DEPENDENCIES
PRIVATE
Gem::HelloGem
)

ly_create_alias(NAME HelloGem.Clients NAMESPACE Gem TARGETS Gem.HelloGem.Standalone)

注意:实际工程中会使用模板生成的文件集和别名;确保目标被项目的 Launcher/Editor 依赖。

  1. 启用与测试
  • 启用 Gem:o3de.py enable-gem -gn HelloGem -pp
  • 构建并运行 Editor;在 Console 或 Python 控制台中:
    • from azlmbr import HelloGemSystem
    • obj = HelloGemSystem()
    • print(obj.Add(3, 4)) # 7


六、编辑器扩展示例(带 Qt 面板)

目标:在 Editor 中添加一个“Hello 面板”,有一个按钮能调用系统组件的 Add,并展示结果。

要点概述:

  • 定义 EditorSystemComponent,注册菜单与面板命令。
  • 使用 AzToolsFramework::ActionManagerInterface 注册菜单项。
  • 创建一个 QDockWidget,嵌入自定义 QWidget。

关键步骤(概览):

  • EditorModule.cpp 中在构造插入 EditorSystemComponent 描述符。
  • 在 EditorSystemComponent::Activate 中注册动作、创建 Dock。
  • 通过 Bus 与 Runtime System 通信或直接调用共享逻辑。

提示:完整 Qt 代码略长,实际实现时参考 AzToolsFramework 示例(例如 AtomLyIntegration、ScriptCanvasEditor 的注册模式)。


七、资产构建器(AssetBuilder)扩展示例(概念)

场景:自定义 .foo 文本文件,生成 .azasset。

步骤:

  • 注册 Builder Descriptor:名称、版本、patterns("*.foo")、BusId。
  • CreateJobs:为每个 .foo 生成一个 Job(每平台一次),指定输出产品扩展。
  • ProcessJob:读取 .foo,转换为二进制数据,写入输出产品目录,填充 JobProduct。
  • 在 gem.json 中为 "AssetBuilder" 添加 user_tags,并确保在 Editor 启动时 Asset Processor 能加载该 Builder。


八、关键要点与开发规范

  • 版本与兼容
    • 指定 gem.json 的 "version",采用语义化版本(MAJOR.MINOR.PATCH)。
    • 在 O3DE 升级时,留意 AzCore/AzFramework API 变化、CMake 宏调整、RHI/RPI 变动。
    • 在 Reflect Version 变更时提供版本迁移(SerializeContext Version 与版迁器)。
  • 代码质量
    • 严格使用 AZ_RTTI、AZ_CLASS_ALLOCATOR;避免 new/delete,使用 AZStd::unique_ptr/IntrusivePtr。
    • 明确组件服务依赖,避免循环依赖;用 Requires/Dependent Services 表达约束。
    • EBus 使用:高频调用避免 EBus 带来的虚调用开销,可用 Direct API 或 Event/Handler 缓存。
  • 脚本与工具
    • BehaviorContext 命名清晰,方法注释;避免暴露未稳定 API。
    • Python 工具使用 azlmbr API;脚本放在 Scripts/ 并在 Tools/Registry 注册到菜单。
  • 平台与构建
    • 使用 PAL 宏 AZ_TRAIT_XXX 控制平台特性。
    • 外部第三方库通过 3rdParty 集成,注意静/动态链接许可证与发布体积。
  • 性能与内存
    • 使用 AZ::Interface 提供服务定位器式访问。
    • 使用 AZ_PROFILE_FUNCTION/AZ_TracePrintf 进行性能与日志。
  • 资源与数据驱动
    • 用 Registry 默认设置暴露可调参数;使用 CVAR(AZ_CVAR)提供运行时调优。


九、测试、CI 与发布

  • 单元测试
    • 使用 GoogleTest 集成:ly_add_googletest;覆盖组件逻辑、数据转换。
    • 对 BehaviorContext 绑定的 smoke test(确认方法可被调用)。
  • 自动化与编辑器测试
    • Python 测试脚本驱动 Editor:启动、加载关卡、调用你的工具命令,校验结果/日志。
    • Asset Processor 测试:投递输入资源,验证产物生成。
  • 静态检查与格式化
    • clang-tidy、cpplint;统一格式(.clang-format 与 O3DE 默认)。
  • CI
    • 配置 GitHub Actions/Azure Pipelines:多平台构建、单元测试、打包 Gem 工件(.zip)。
  • 打包与分发
    • 清单:gem.json、LICENSE、README、CHANGELOG、Docs/、Code/、Assets/、Registry/、CMakeLists.txt。
    • 通过 o3de 清单注册(o3de_manifest.json),允许他人 o3de.exe/o3de.py register -gp 拉取。
    • 提供示例项目或最小关卡,降低集成门槛。


十、常见问题与排错

  • Gem 未出现在项目启用列表
    • 检查 gem.json 路径与 UUID;是否已 register -gp;是否满足平台要求。
  • 编译错误:未找到目标/库
    • CMake 目标未创建或别名未与 Editor/Launcher 链接;检查 ly_create_alias 与 BUILD_DEPENDENCIES。
  • BehaviorContext 未见到类/方法
    • Reflect 未被调用:确保 SystemComponent/Module 注册到描述符集合;确认编辑器/运行时加载了模块。
  • Editor 崩溃/空白面板
    • Qt 线程问题:UI 操作需在主线程;使用主线程调度器。
  • AssetBuilder 不工作
    • 未在 Builder Bus 注册或 patterns 配置不匹配;查看 Asset Processor 日志与 cache。


十一、实施清单(Checklist)

  • 元数据
    • gem.json 完整、UUID 唯一、版本语义化、依赖列表准确。
  • 架构
    • Module + SystemComponent 完整;服务声明齐全;Reflect 覆盖 Serialize/Behavior/Edit。
  • 构建
    • CMake 目标正确定义;平台宏设置;第三方库处理。
  • 脚本与工具
    • Python 命令可运行;ActionManager 菜单项显示;文档说明。
  • 测试
    • 单元测试、脚本测试、Asset Processor 测试通过;性能热点分析。
  • 文档
    • README、使用指南、API 示例、变更记录。
  • 发布
    • 打包、校验 LICENSE、兼容 O3DE 版本说明、示例工程。


十二、进阶主题与实践建议

  • 多模块 Gem 切分:将 Runtime/Editor/Builders 拆分为独立 target,减少链接体积与依赖耦合。
  • 数据驱动配置:在 Registry 提供默认 CVAR/设置,允许用户覆盖。
  • 热重载与开发效率:利用 Editor 的 Python 控制台和工具菜单实现快速迭代。
  • 可观测性:集成 ImGui/Telemetry(遵循许可)或使用 O3DE Profiler 与 AZ::Metrics。
  • 跨平台资源路径与文件系统:使用 AZ::IO::FileIOBase 和 PathView,避免平台差异。
  • 安全与稳定:对外部输入做校验;避免未经限制的脚本执行;注意线程安全(EBus Handler 在 Activate/Deactivate 生命周期内注册/注销)。


十三、示例 Gem 方向建议(可作为模板起点)

  • Gameplay Utilities:时间轴、状态机(BehaviorContext 暴露)。
  • Networking Helper:HTTP/GRPC 客户端(封装 curl/Protobuf)。
  • Editor Productivity:批量重命名、批量材质替换、资源清理。
  • Asset Import:定制格式导入,生成自定义组件资源。
  • Analytics/Telemetry:事件上报与离线缓存。


十四、规格与文档模板建议

  • 规格说明书(SRS)要点
    • 背景与目标
    • 功能列表(用例、输入输出、错误码)
    • 非功能需求(性能、内存、平台、可扩展性、安全)
    • 接口规范(EBus/Behavior API、CVAR、配置文件结构)
    • 资源规格(资产扩展名、构建产物、缓存策略)
    • 兼容性矩阵(O3DE 版本、OS、编译器)
    • 测试计划与验收标准
    • 版本策略与弃用策略
  • API 文档结构
    • 命名空间、类清单、方法签名、参数/返回值、示例代码、注意事项。
    • 变更记录:新增/修改/弃用标签。
  • 代码注释规范
    • Doxygen 风格注释;示例:
      • @brief, @param, @return, @note, @warning
    • 反射版本注释:说明字段新增/迁移逻辑。


结语

以上指南覆盖了 O3DE 插件(Gem)开发的完整生命周期与关键实现路径:从环境搭建、模块/组件/反射、编辑器与资产管线扩展,到测试发布与规范化管理。你可以直接据此搭建一个最小 Gem,逐步添加 Editor/AssetBuilder 能力,并按 Checklist 与规范完善工程。

如果你希望,我可以:

  • 依据你的目标功能,生成一套定制的 gem.json、CMakeLists 和完整最小代码骨架。
  • 为某个具体扩展(例如 Editor 面板或 AssetBuilder)提供完整的可编译样例。
  • 根据你的团队规范生成 SRS/API 文档模板与 CI 配置。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值