UE4 如何在 commandlet 中加载关卡?

问题描述 投票:0回答:4

我想用 commandlet 记录所有 actors,所以我写了这样的代码。

#include "MyCommandlet.h"
#include "Kismet/GameplayStatics.h"
#include "Engine/StaticMeshActor.h"
#include "MyCharacter.h"

int32 UMyCommandlet::Main(const FString& Params)
{
    TArray<AActor*> arrActors;
    UWorld* World = GetWorld();

    if (World)
    {
        UGameplayStatics::GetAllActorsOfClass(GetWorld(), AMyCharacter::StaticClass(), arrActors);

        for (int i = 0; i < arrActors.Num(); i++)
        {
            AMyCharacter* pCharacter = dynamic_cast<AMyCharacter*>(arrActors[i]);

            UE_LOG(LogTemp, Display, TEXT("%d"), pCharacter->TestValue);

        }   
    }

    return 0;
}

但是 GetWorld() 返回 NULL。我认为原因是当调用 commandlet 时,没有加载任何级别。

实际上虚幻引擎文件说 “Commandlets 在“原始”环境中执行,在该环境中,游戏未加载,客户端代码未加载,关卡未加载,参与者也不存在。” 链接:https://docs.unrealengine.com/4.26/en-US/API/Runtime/Engine/Commandlets/UCommandlet/#:~:text=UCommandlet%20%3A%20public%20UObject-,Remarks,-Commandlet %20

那我怎样才能在 commandlet 中加载关卡或 getworld() ...??

c++ unreal-engine4 unreal-engine5
4个回答
0
投票

试试这个:

FString levelAssetPath = TEXT("/Game/Maps/SomeLevel");
GEditor->GetEditorSubsystem<ULevelEditorSubsystem>()->LoadLevel(levelAssetPath);

0
投票

也许你可以创建一个 FAutoConsoleCommandWithWorldAndArgs 来绑定你的函数,它会传入一个 UWorld。

FAutoConsoleCommandWithWorldAndArgs AbilitySystemToggleDebugHUDCommand(
TEXT("Your Command"),
TEXT("Your Help Text"),
FConsoleCommandWithWorldAndArgsDelegate::CreateStatic(Your_Function)
);

static void Your_Function(const TArray<FString>& Args, UWorld* InWorld);

0
投票

这个世界在 commandlet 中不应该为 NULL:

UWorld* World = GEditor->GetEditorWorldContext().World();


0
投票

可以参考

UImportAssetsCommandlet::LoadLevel
中的
Engine\Source\Editor\UnrealEd\Private\Commandlets\ImportAssetsCommandlet.cpp

手动加载umap并初始化UWorld:

bool UImportAssetsCommandlet::LoadLevel(const FString& LevelToLoad)
{
    bool bResult = false;

    if (!LevelToLoad.IsEmpty())
    {
        UE_LOG(LogAutomatedImport, Log, TEXT("Loading Map %s"), *LevelToLoad);

        FString Filename;
        if (FPackageName::TryConvertLongPackageNameToFilename(LevelToLoad, Filename))
        {
            UPackage* Package = LoadPackage(NULL, *Filename, 0);

            UWorld* World = UWorld::FindWorldInPackage(Package);
            if (World)
            {
                // Clean up any previous world.  The world should have already been saved
                UWorld* ExistingWorld = GEditor->GetEditorWorldContext().World();

                GEngine->DestroyWorldContext(ExistingWorld);
                ExistingWorld->DestroyWorld(true, World);

                GWorld = World;

                World->WorldType = EWorldType::Editor;

                FWorldContext& WorldContext = GEngine->CreateNewWorldContext(World->WorldType);
                WorldContext.SetCurrentWorld(World);

                // add the world to the root set so that the garbage collection to delete replaced actors doesn't garbage collect the whole world
                World->AddToRoot();

                // initialize the levels in the world
                World->InitWorld(UWorld::InitializationValues().AllowAudioPlayback(false));
                World->GetWorldSettings()->PostEditChange();
                World->UpdateWorldComponents(true, false);

                bResult = true;
            }
        }
    }
    else
    {
        // a map was not specified, ignore
        bResult = true;
    }

    if (!bResult)
    {
        UE_LOG(LogAutomatedImport, Error, TEXT("Could not find or load level %s"), *LevelToLoad);
    }

    return bResult;

}

然后使用

TActorIterator
登出Actor

    if (World)
    {
        int32 ActorCount = 0;
        for (TActorIterator<AActor> It(World); It; ++It)
        {
            AActor* CurrentActor = *It;
            FString ActorName = CurrentActor->GetName();

            UE_LOG(LogTemp, Log, TEXT("Actor: %s"), *ActorName);
            ActorCount++;
        }

        UE_LOG(LogTemp, Log, TEXT("Total number of actors: %d"), ActorCount);
    }
    else
    {
        UE_LOG(LogTemp, Error, TEXT("Failed to load the specified map."));
    }
© www.soinside.com 2019 - 2024. All rights reserved.