UE4 CommandLet 学习和使用笔记

Viewed 7

首发:

UE4 CommandLet 学习和使用笔记

有什么用

  • 借助 Commandlet ,我们无需打开 UE 编辑器,即可在命令行下执行某段 C++ 代码。可用来批量处理 UE 工程中的资源等。结合 Jenkins 等自动化处理方案,可较方便地实现 UE 工程的自动化处理。
  • 典型应用场景如 Resave Packages 、Fixup Redirects、Cooking、Localization Pipeline 等。

怎么制作

选个好目录(编辑器模块或插件)

  • 由于编辑器功能依赖于 Editor 相关模块,所以应该写在非游戏模块。我们可以新建一个 Editor 相关的模块,或新建一个 Plugin 来写这些逻辑。
  • 关于新建 Editor 模块或 Plugin 的方法参见具体文档,此处仅贴出示例代码的关键结构。

新建类,类名以 Commandlet 结尾,继承 UCommandlet 。

重写 Main 方法(完整代码会在后面贴出)

  • ExampleCommandlet.h

  • ExampleCommandlet.cpp

在 Main 中写想要的处理逻辑

  1. 首先通过 ParseCommandLine 把参数解析出来

2 借助 UKismetStringLibrary::ParseIntoArray 解析列表型参数

  1. 根据解析出来的参数,结合通用的编辑器API(如 AssetRegistry 等),做自己想做的事。

(可选)可先在 VisualStudio 中调通代码。

(可选)可自定义这个 commandlet 的日志类型,方便日志归类和检索。

  • 先声明:DEFINE_LOG_CATEGORY_STATIC(LogCommandletExample, Log, All);
  • 再使用:UE_LOG(LogCommandletExample, Log, TEXT("Example commandlet begin to execute ."));
  • 结果

附:例子的完整代码。

  • ExampleCommandlet.h
// Fill out your copyright notice in the Description page of Project Settings.

# pragma once

# include "CoreMinimal.h"
# include "Commandlets/Commandlet.h"
# include "ExampleCommandlet.generated.h"

DEFINE_LOG_CATEGORY_STATIC(LogCommandletExample, Log, All);


/**
 * 
 */
UCLASS()
class MARSEXAMPLEEDITOR_API UExampleCommandlet : public UCommandlet
{
	GENERATED_BODY()

public:
	UExampleCommandlet();

	virtual int32 Main(const FString& Params) override;
};
  • ExampleCommandlet.cpp
// Fill out your copyright notice in the Description page of Project Settings.


# include "ExampleCommandlet.h"

# include "Kismet/KismetStringLibrary.h"

UExampleCommandlet::UExampleCommandlet()
{
	LogToConsole = true;
}

int32 UExampleCommandlet::Main(const FString& Params)
{
	UE_LOG(LogCommandletExample, Log, TEXT("Example commandlet begin to execute ."));

	TArray<FString> Tokens;
	TArray<FString> Switches;
	TMap<FString, FString> ParamsMap;
	ParseCommandLine(*Params, Tokens, Switches, ParamsMap);

	const FString& TmpStringParamsKey = TEXT("StringParamsKey");
	TArray<FString> StringParams;
	if (ParamsMap.Contains(TmpStringParamsKey))
	{
		FString StringParamsValueString = ParamsMap[TmpStringParamsKey];
		StringParams = UKismetStringLibrary::ParseIntoArray(StringParamsValueString, TEXT("+"), true);
	}

	// do something with parameters

	return 0;
}

怎么使用

  1. 首先确保你的机器上安装有 UE 编辑器,且已经存在了对应的工程(也即你要为之使用 Commandlet 的工程)
  2. 在任意目录启动 CMD 窗口,输入如下命令。
  • CMD 格式
    {UE4Editor.exe full path} {uproject full path} -skipcompile -run {commandlet name without commandlet suffix} {parameters for your commandlet}
  • CMD 示例
    I:\\UE\\UE_4.27\\Engine\\Binaries\\Win64\\UE4Editor.exe G:\\workspace\\\unreal\\\MarsExample\\MarsExample.uproject -skipcompile -run=Example -StringParamsKey=Value1+Value2+Value10086
  1. 等待执行完毕,判断成功还是失败。
  2. 默认情况下日志在 Saved\Logs{YourProject}.log 中。
  3. 你也可以通过 “LOG=” 指定 log 文件地址(在 Saved\Logs 文件夹下)。如示例所示。

什么原理

概要

  • UE 编辑器启动之后,在 FEngineLoop::PreInitPostStartupScreen 中,根据 Switches 以 RUN= 开头,判断出 bHasCommandletToken 为 true , 之后拿到对应的 commandlet 并执行其 Main 方法。

堆栈

问答

  • C++里如何知道当前是否运行在 commandlet 环境下?
  • 使用API:IsRunningCommandlet

参考资料

UE4:如何编写命令行开关
【UE4编辑器开发】Commnetlet自定义命令行工具

**声明:**本文来自公众号:GameDevLearning,转载请附上原文链接及本声明。

0 Answers