UE4 Commandlet中如何加载关卡获取有效UWorld指针?
问题原因
Commandlet默认运行在无游戏逻辑、无客户端实例、无预加载关卡的原始环境,直接调用GetWorld()必然返回空指针,不存在已生成的Actor实例,必须主动加载目标关卡才能拿到有效的UWorld上下文。
实现步骤
- 引入关卡加载、Actor遍历所需的依赖头文件
- 从Commandlet启动参数中读取待加载的关卡路径,调用Editor侧地图加载接口获取有效
UWorld指针,加载完成前不要调用任何依赖World上下文的接口(比如UGameplayStatics系列接口) - 使用
TActorIterator遍历关卡内Actor,该接口比UGameplayStatics::GetAllActorsOfClass更适配Commandlet的非游戏运行环境,不会出现上下文找不到的问题
完整可运行代码
#include "MyCommandlet.h" #include "Engine/World.h" #include "FileHelpers.h" #include "EngineUtils.h" #include "MyCharacter.h" int32 UMyCommandlet::Main(const FString& Params) { // 解析传入的关卡路径 FString MapPath; if (!FParse::Value(*Params, TEXT("map="), MapPath) || MapPath.IsEmpty()) { UE_LOG(LogTemp, Error, TEXT("未指定待加载关卡,请通过 -map=关卡全路径 参数传入,例:-map=/Game/Maps/TargetMap")); return 1; } // 加载关卡,获取有效UWorld指针 UWorld* LoadedWorld = FEditorFileUtils::LoadMap(MapPath, false, false); if (!LoadedWorld) { UE_LOG(LogTemp, Error, TEXT("关卡加载失败,路径:%s"), *MapPath); return 1; } // 遍历关卡内所有AMyCharacter实例 for (TActorIterator<AMyCharacter> ActorIt(LoadedWorld); ActorIt; ++ActorIt) { AMyCharacter* TargetCharacter = *ActorIt; if (IsValid(TargetCharacter)) { UE_LOG(LogTemp, Display, TEXT("角色TestValue值:%d"), TargetCharacter->TestValue); } } // 用完销毁World释放内存 LoadedWorld->DestroyWorld(false); return 0; }
运行注意事项
- 对应模块的Build.cs需要添加Editor依赖模块:
"UnrealEd", "EditorStyle",否则无法调用Editor侧的地图加载接口 - 启动Commandlet时需要传入关卡路径、无人值守运行参数,示例命令:
UE4Editor-Cmd.exe 你的项目路径.uproject -run=MyCommandlet -map=/Game/Maps/YourTargetMap -unattended -nopause -nosplash - 如果需要遍历关卡内所有Actor,将
TActorIterator的模板参数替换为AActor即可。
内容的提问来源于stack exchange,提问作者user19246061
相关产品推荐
相关产品推荐

