5.4 自动化与 CI:命令行运行编辑器

为什么要命令行化

把工具从「人点按钮」变成「机器定期跑」,工具的价值放大十倍。典型场景:

  • 每日构建跑资产检查器,报告问题数
  • CI 门禁:禁止「有 broken 引用的提交」
  • 烘焙/打包前自动执行清理工具
  • 夜间批处理:导入外部工具产生的数据

官方总览见「编辑器的脚本与自动化」(https://www.wanxiangyundang.top/read/unreal-engine-5-8-docs/scripting-and-automating-the-u-0a4d)。

命令行运行编辑器

# 无界面运行(Server/无头模式)
UnrealEditor.exe MyProject.uproject -run=MyCommandlet -NoShaderCompile -Unattended -NoLoadStartupPackages

# 执行 Python 脚本
UnrealEditor.exe MyProject.uproject -ExecPythonScript="check_assets.py" -Unattended -Quit

# 执行命令行命令(Commandlet)
UnrealEditor.exe MyProject.uproject -run=AssetAudit /Game/Items

关键参数:

参数 作用
-run=Xxx 执行自定义 Commandlet
-ExecPythonScript=... 直接跑 Python 脚本
-Unattended 无人值守(无 UI 弹窗)
-NoShaderCompile 不编译 Shader(加速启动)
-Quit 执行完退出
-NoLoadStartupPackages 减少加载量

自定义 Commandlet

class UMyAuditCommandlet : public UCommandlet
{
    GENERATED_BODY()
public:
    virtual int32 Main(const FString& Params) override
    {
        // 解析参数、跑检查、写报告文件、返回退出码
        return bAllOk ? 0 : 1;         // CI 用退出码判断成败
    }
};

CI 侧只看退出码与报告文件。工具的双重身份:有 UI 版本给人用,Commandlet 版本给 CI 用——核心逻辑写一份,两层入口。

报告格式

CI 用的报告要点:

  • 人话摘要(开头给数量与状态)
  • 机器可读(JSON/CSV,下游工具可解析)
  • 稳定字段(工具版本、运行时间、项目路径)
{
  "tool": "AssetValidator", "version": 12,
  "timestamp": "2026-11-08T10:00:00",
  "summary": {"total_assets": 12500, "problems": 37, "errors": 3},
  "problems": [ {"path": "/Game/X", "type": "MISSING_REF", "detail": "..." } ]
}

集成到 CI 的经验

  1. 从手动触发开始:先把 CI job 做成手动跑,稳定后再排定时
  2. 失败门槛分级:第一阶段只 warning 不阻断;稳定后 errors 才阻断提交
  3. 报告保留历史:今天的数字对比上周的,能看出「项目在变好还是变坏」
  4. 时间预算:Commandlet 启动编辑器本身要 1~2 分钟——做到「跑完整个检查 < 10 分钟」才有用

常见坑

  • Python 版本:UE 内置 Python 环境,别用系统的 pip 包
  • 权限/路径:CI 机器上跑没有交互登录,用户目录/磁盘权限不同。所有路径用项目相对 + SystemLibrary 取根路径
  • 缓存:DerivedDataCache 的位置在 CI 上要可配置(充分预热否则慢得不能看)
  • 引擎版本:每个引擎版本一个 CI Job,别在一台上混装

心得:工具一旦上了 CI,就「再也不能回头」——团队依赖它之后,任何让它变慢/误报的改动都会被打回来。发布 CI 版本前,先内部跑两周的影子模式(只报告不阻断)验证。