编写自己的 uBot Package
需要:uBotCore 0.1.x
把一个 UE 插件写成 uBot Package:.uplugin 里的 UBot 块写什么、依赖的版本约束(version constraint)怎么写、索引条目长什么样,以及怎样校验。
| 键 | 必填 | 写法 |
|---|---|---|
VersionName(UE 原生) |
是 | 语义化版本(SemVer),如 0.1.0 |
UBot.Layer |
是 | Foundation、Capability、Adapter、Content |
UBot.Repository |
否 | git 仓库地址,uBot Manager 用它安装和更新 |
UBot.Requires |
否 | 依赖列表,每项有 Name、Version(版本约束,缺省为任意版本)和 Optional(默认 false) |
UBot.Provides |
否 | 这个 Package 提供的能力键(capability key),如 Sensor.IMU |
UBot.Tags |
否 | 标签,如 sensor |
UBot.EnginePlugins |
否 | 必须启用的引擎插件,如 ChaosVehiclesPlugin |
.uplugin 里的 UBot 块
Section titled “.uplugin 里的 UBot 块”只有带 UBot 对象的插件才会被当作 uBot Package。UE 原生的 Plugins 依赖仍然是 UE 强制执行的机制,UBot 块在它之上补充版本范围和目录信息,所以依赖要在两处都写。
{ "FileVersion": 3, "VersionName": "0.1.0", "FriendlyName": "My Range Sensor", "Description": "Simulated range sensor for uBot.", "DocsURL": "https://github.com/your-name/MyRangeSensor", "Modules": [ { "Name": "MyRangeSensor", "Type": "Runtime", "LoadingPhase": "Default" } ], "Plugins": [ { "Name": "UBotCore", "Enabled": true } ], "UBot": { "Layer": "Capability", "Repository": "https://github.com/your-name/MyRangeSensor.git", "Requires": [ { "Name": "UBotCore", "Version": "^0.1.0" } ], "Provides": [ "Sensor.Range" ], "Tags": [ "sensor" ] }}Optional 为 true 的依赖只在对方已经安装但版本不满足时才算问题,也不构成依赖边。
版本约束语法
Section titled “版本约束语法”Requires[].Version、索引里的 requires[].version 和 engine,以及蓝图节点 Is uBot Package Version Satisfied 用同一套语法。
| 写法 | 含义 |
|---|---|
空字符串、* |
任意版本 |
1.2.3、=1.2.3 |
恰好等于 1.2.3 |
>=1.2.3、>1.2.3、<=1.2.3、<1.2.3 |
比较 |
^1.2.3 |
>=1.2.3 <2.0.0 |
^0.2.3 |
>=0.2.3 <0.3.0 |
^0.0.3 |
>=0.0.3 <0.0.4 |
~1.2.3 |
>=1.2.3 <1.3.0 |
~1 |
>=1.0.0 <2.0.0 |
1.2、=1.2 |
不完整的版本按范围算:>=1.2.0 <1.3.0 |
>=1.0.0 <2.0.0 |
区间,所有比较器同时成立 |
^锁定最左边不为 0 的那一段:^0.1.0只接受 0.1.x,^0.0.3只接受 0.0.3。- 版本号接受
1、1.2、1.2.3,可以带前缀v和-prerelease,+build被忽略。 - 多个比较器用空格分隔,运算符和版本之间也可以有空格(
>= 1.0)。 - 由
^、~和不完整版本产生的上界会排除该上界本身的预发布版本,例如^1.2.3不接受2.0.0-beta。
索引(index)是 uBot Manager 和编辑器读取 Package 列表的地方,格式版本是 2(formatVersion)。条目里的每一项都要和 Package 仓库里的 .uplugin 保持一致:
| 索引 | 对应的 .uplugin 键,或说明 |
|---|---|
name |
插件名,字母、数字和 _,不以数字开头 |
friendlyName、docsUrl |
FriendlyName、DocsURL |
layer |
UBot.Layer |
repository |
UBot.Repository;有可安装版本时必填 |
folder |
只在索引里,可选:安装目录名,插件装到 Plugins/uBot/<folder>;省略时取仓库地址的最后一段,去掉 .git |
tags |
UBot.Tags |
versions[].version |
VersionName(该标签处的值) |
versions[].ref |
要检出的 git 标签,如 v0.1.0;规划中的版本("planned": true)不写 |
versions[].requires |
UBot.Requires(name、version、optional 对应 Name、Version、Optional) |
versions[].provides |
UBot.Provides |
versions[].enginePlugins |
UBot.EnginePlugins |
versions[].engine |
对 UE 版本的约束,如 ~5.5;只在索引里 |
versions[].binaries |
只在索引里,可选:这个版本的预编译压缩包,按 UE 版本和平台给出 url、sha256 和 size;由 ubot package --update-index 写入,不用手写 |
description |
只在索引里:en 必填,zh-CN 建议填写 |
一个完整的索引文件:
{ "formatVersion": 2, "name": "my-packages", "packages": [ { "name": "MyRangeSensor", "friendlyName": "My Range Sensor", "description": { "en": "Simulated range sensor.", "zh-CN": "测距传感器仿真。" }, "layer": "Capability", "repository": "https://github.com/your-name/MyRangeSensor.git", "docsUrl": "https://github.com/your-name/MyRangeSensor", "tags": [ "sensor" ], "versions": [ { "version": "0.1.0", "ref": "v0.1.0", "engine": "~5.5", "requires": [ { "name": "UBotCore", "version": "^0.1.0" } ], "enginePlugins": [], "provides": [ "Sensor.Range" ] } ] } ]}发布一个新版本
Section titled “发布一个新版本”-
改版本号
修改
.uplugin的VersionName(需要时也改UBot块),提交。 -
打标签并推送
标签叫
v加版本号,要先推送,再写进索引。uBot Manager 用git clone --branch <ref>安装。终端窗口 git tag v0.1.0git push origin v0.1.0 -
在索引里追加一项
在这个 Package 的
versions里追加新版本,ref写标签名。旧版本留着,用户需要降级或固定版本。 -
制作预编译包(可选)
用
ubot package编译并打包,同时把下载地址和 SHA-256 写进索引的binaries。新版本还没有推送,所以用--index指向本地的索引文件:终端窗口 ubot --index Index/index.json package MyRangeSensor --out E:\release --update-index Index/index.json再把
E:\release里的 zip 上传到对应标签的 GitHub Release。参数和要求见命令行 ubot。 -
校验并推送
运行
ubot index validate,见下一节。有预编译包时先上传压缩包,再提交并推送索引:索引一推送,用户就会开始下载。
让工程读到你的索引
Section titled “让工程读到你的索引”| 谁读 | 怎么加 |
|---|---|
| uBot Manager | 「设置 > Package 索引 > 索引源」,添加 https:// 地址或文件路径。同一个 Package 以排在前面的源为准 |
| 编辑器和 commandlet | 项目设置「uBot Core」的 AdditionalPackageIndexFiles。同名条目由后加载的覆盖 |
[/Script/UBotCore.UBotCoreSettings]+AdditionalPackageIndexFiles=Config/uBotPackages.json| 方式 | 检查什么 | 入口 |
|---|---|---|
| 编辑器启动日志 | UBot 块和依赖;每个问题是一条 LogUBot 警告,最后一行是 uBot packages: N installed, M enabled, K problem(s). |
打开工程(bValidatePackagesOnStartup 默认开启) |
| uBot 面板 | 同上,显示在「Problems」分区 | 「Window > uBot」 |
| commandlet | 同上;有问题时退出码为 1 | -run=UBotPackage -Validate |
ubot index validate |
索引文件的结构和跨条目的规则;不需要工程,不访问网络 | uBot Manager 的命令行 |
$Editor = '<UE_5.5>\Engine\Binaries\Win64\UnrealEditor-Cmd.exe'$Project = '<Project>\<Project>.uproject'
& $Editor $Project -run=UBotPackage -List # 确认 Package 被识别& $Editor $Project -run=UBotPackage -Validate # 有任何问题则退出码为 1
ubot index validate Index/index.json # 加 --json 得到 { ok, errors, warnings }编辑器端会报告这些问题:
VersionName缺失或无法解析,或者UBot块缺少必填的键。- 必需的 Package 不存在或未安装,已安装的依赖不满足版本约束。
- 已启用的 Package 依赖了未启用的 Package。
- 版本约束无法解析,依赖循环。
ubot index validate 的输出是英文,有错误时退出码为 1,只有警告时为 0:
error: packages[0] (UBotFoo).versions[0]: "ref" is required for a version that is not planned.Index/index.json: 1 error(s), 0 warning(s).它只读指定的文件,不比较索引和 .uplugin。没安装的 Package 按索引规划,装好以后按 .uplugin 规划,两边不一致就会得到不同的结果,所以改完要自己对一遍。
- Package 查询与编辑器面板:uBot 面板、运行时状态和命令行
-run=UBotPackage。 - 命令行 ubot:
ubot的获取方式和常用命令。 - 为自定义传感器添加 ROS 发布器:Package 之间用扩展点互相扩展。