Switching between UWorlds

Hi all. I want the player to be able to view the selected character or items in another created scene during the game. In my opinion, the correct solution is to create a new UWorld and switch to it, and then, after finishing things, go back.
I was able to create and get some work done with a new UWorld which has a rotating 2d scene grab for testing that renders into a texture that renders as it should in UMG. Also at this level there is a character in which the player could move in.
But now I need help switching to this new level and then back. what I don’t understand is how should I change the viewport to the new created level and switch to the new player controller already on that new level to receive input.


#include "GameBFL.h"

#include "Serialization/ObjectAndNameAsStringProxyArchive.h"

#include "EngineUtils.h"
#include "Kismet/GameplayStatics.h"
#include "GameFramework/GameModeBase.h"

#include "NavigationSystem.h"
#include "NavMesh/RecastNavMesh.h"

#include "UObject/UObjectHash.h"



UWorld* UGameBFL::GetMainWorld()
{
	return GEngine->GetCurrentPlayWorld();
}

void UGameBFL::ChangeWorld(UObject* World)
{
	//GEngine->GameViewport->Viewport;
	//GetGameViewport()->bDisableWorldRendering;
	//WorldContext->GameViewport;
}




FDelegateHandle UGameBFL::CleanupHandle;
FDelegateHandle UGameBFL::TickHandle;
TArray<UWorld*> UGameBFL::CreatedWorlds;


void UGameBFL::CreateNewWorld2(const UObject* WorldContextObject, const TSoftObjectPtr<UWorld> Level, UWorld*& World)
{

	UWorld* NewWorld = nullptr;

	const FString LevelName2 = FPackageName::ObjectPathToPackageName(Level.ToString());
	//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("level name = %s"), *LevelName2));

	UPackage* WorldPackage = FindPackage(nullptr, *LevelName2);
	if (WorldPackage == nullptr)
	{
		WorldPackage = LoadPackage(nullptr, *LevelName2, ELoadFlags::LOAD_None);
		if (!WorldPackage)
		{
			GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Package not loaded")));
			return;
		}

	}


	UWorld* PackageWorld = UWorld::FindWorldInPackage(WorldPackage);



	UPackage* NewWorldPackage = CreatePackage(nullptr);
	//NewWorldPackage->SetPackageFlags(PKG_PlayInEditor);
	//NewWorldPackage->PIEInstanceID = PIEInstanceID;
	//NewWorldPackage->FileName = PackageFName;
	//NewWorldPackage->SetGuid(EditorLevelPackage->GetGuid());
	//NewWorldPackage->MarkAsFullyLoaded();


	FObjectDuplicationParameters Parameters(PackageWorld, NewWorldPackage);
	Parameters.DestName = PackageWorld->GetFName();
	Parameters.DestClass = PackageWorld->GetClass();
	Parameters.DuplicateMode = EDuplicateMode::PIE;
	Parameters.PortFlags = EPropertyPortFlags::PPF_Duplicate;

	NewWorld = CastChecked<UWorld>(StaticDuplicateObjectEx(Parameters));

	//NewWorld = UWorld::DuplicateWorldForPIE(LevelName2, PackageWorld);
	//if (!NewWorld)
	//{
	//	return;
	//}


	//const FString WorldNameString = "CreatedMap" + FString::FromInt(FMath::RandRange(0, 100));
	//NewWorld = UWorld::CreateWorld(EWorldType::PIE, true, FName(*WorldNameString));
	//NewWorld = UWorld::CreateWorld(EWorldType::Game, true, FName("CreatedMap"), WorldPackage);


	NewWorld->SetShouldTick(true);


	FWorldContext& WorldContext = GEngine->CreateNewWorldContext(EWorldType::Game);
	WorldContext.OwningGameInstance = UGameplayStatics::GetGameInstance(WorldContextObject);
	//WorldContext.PIEInstance = -1;
	NewWorld->SetGameInstance(UGameplayStatics::GetGameInstance(WorldContextObject));
	////NewWorld->WorldType = WorldContext.WorldType;
	NewWorld->WorldType = EWorldType::PIE;
	WorldContext.SetCurrentWorld(NewWorld);



	//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("CreateWorld: %s"), *NewWorld->GetFName().ToString()));

	//// In the PIE case the world will already have been initialized as part of CreatePIEWorldByDuplication
	if (!WorldContext.World()->bIsWorldInitialized)
	{
		WorldContext.World()->InitWorld();
	}

	/*FNavigationSystemRunMode ResolvedRunMode(FNavigationSystemRunMode::GameMode);
	switch (NewWorld->WorldType)
	{
	case EWorldType::Editor:
	case EWorldType::EditorPreview:
		ResolvedRunMode = FNavigationSystemRunMode::EditorMode;
		break;

	case EWorldType::PIE:
		ResolvedRunMode = FNavigationSystemRunMode::PIEMode;
		break;

	case EWorldType::Game:
	case EWorldType::GamePreview:
	case EWorldType::GameRPC:
		ResolvedRunMode = FNavigationSystemRunMode::GameMode;
		break;

	case EWorldType::Inactive:
	case EWorldType::None:
		ResolvedRunMode = FNavigationSystemRunMode::InvalidMode;
		break;

	default:
		UE_LOG(LogNavigation, Warning, TEXT("%s Unhandled world type, defaulting to FNavigationSystemRunMode::InvalidMode."), ANSI_TO_TCHAR(__FUNCTION__));
		ResolvedRunMode = FNavigationSystemRunMode::InvalidMode;
	}

	if (NewWorld->GetNavigationSystem())
	{
		NewWorld->GetNavigationSystem()->InitializeForWorld(*NewWorld, ResolvedRunMode);
	}*/
	//else if (ResolvedRunMode == FNavigationSystemRunMode::EditorMode)
	//{
	//	DiscardNavigationDataChunks(WorldOwner);
	//}



	FURL URL;
	//FURL URL(&WorldContext.LastURL, *NewWorld->GetFName().ToString(), ETravelType::TRAVEL_Absolute);
	//URL.AddOption(TEXT("GAME=/Game/ThirdPersonCPP/Blueprints/BpGameMode2.BpGameMode2_C"));
	URL.AddOption(TEXT("GAME=/Game/Blueprints/GameModeBP_CreatedWorld.GameModeBP_CreatedWorld_C"));
	WorldContext.World()->SetGameMode(URL);


	//WorldContext.World()->CreateAISystem();





	WorldContext.World()->InitializeActorsForPlay(URL);



	//AActor* lacder = nullptr;

	for (auto actor : NewWorld->PersistentLevel->Actors) {
		UE_LOG(LogTemp, Warning, TEXT("LoadedWorldActorsClasses: %s"), *UKismetSystemLibrary::GetDisplayName(actor));
		//if (actor->GetClass()->GetName() == "BpGameMode2_C")
		//{
		//	//lacder = actor;
		//}
	}
	UFunction* Func = NewWorld->GetAuthGameMode()->GetClass()->FindFunctionByName(FName("Load"));
	if (Func == nullptr) {
		return;
	}
	FStructOnScope FuncParam(Func);
	NewWorld->GetAuthGameMode()->ProcessEvent(Func, FuncParam.GetStructMemory());




	//UNavigationSystemV1 *NavSys = FNavigationSystem::GetCurrent<UNavigationSystemV1>(NewWorld);
	//if (NavSys)
	//{
	//	ANavigationData *UseNavData = NavSys->GetDefaultNavDataInstance(FNavigationSystem::Create);
	//	NavSys->Build();
	//}


	WorldContext.World()->BeginPlay();
	WorldContext.World()->bWorldWasLoadedThisTick = true;




	if (!CleanupHandle.IsValid()) {

		// Tick call in PIE
		TickHandle = FWorldDelegates::OnWorldTickStart.AddLambda([](UWorld* World, ELevelTick TickType, float DeltaSeconds) {
			if (World == GetMainWorld() && GetMainWorld()->WorldType == EWorldType::PIE) {
				for (auto WorldRef : CreatedWorlds) {
					if (WorldRef->ShouldTick())
					{
						WorldRef->Tick(TickType, DeltaSeconds);
						//GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Yellow, FString::Printf(TEXT("TickInWorld: %s"), *WorldRef->GetFName().ToString()));
						//UE_LOG(LogTemp, Warning, TEXT("TickInWorld: %s"), *WorldRef->GetFName().ToString());
					}
				}
			}
		});
		if (TickHandle.IsValid())
		{
			GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Yellow, FString::Printf(TEXT("TickHackSet")));
			UE_LOG(LogTemp, Warning, TEXT("TickHackSet"));
		}

		CleanupHandle = FWorldDelegates::OnPostWorldCleanup.AddLambda([](UWorld *World, bool bSessionEnded, bool bCleanupResources) {
			if (!CreatedWorlds.Contains(World)) {
				FWorldDelegates::OnPostWorldCleanup.Remove(CleanupHandle);
				CleanupHandle.Reset();
				if (TickHandle.IsValid()) {
					FWorldDelegates::OnWorldTickStart.Remove(TickHandle);
					TickHandle.Reset();
				}

				for (auto WorldRef : CreatedWorlds) {
					if (WorldRef) {
						auto Name = WorldRef->GetMapName();
						for (FActorIterator ActorIt(WorldRef); ActorIt; ++ActorIt)
						{
							ActorIt->RouteEndPlay(EEndPlayReason::LevelTransition);
						}

						// Do this after destroying pawns/playercontrollers, in case that spawns new things (e.g. dropped weapons)
						//WorldRef->CleanupWorld();

						//GEngine->WorldDestroyed(WorldRef);



						GEngine->DestroyWorldContext(WorldRef);
						WorldRef->DestroyWorld(true);

						GEngine->TrimMemory();
						//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Created World destroyed: %s"), *WorldRef->GetFName().ToString()));
						UE_LOG(LogTemp, Warning, TEXT("Created World destroyed: %s"), *Name);
					}
				}
				CreatedWorlds.Empty();

				//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("DestroyedWorld: %s"), *World->GetFName().ToString()));
				UE_LOG(LogTemp, Warning, TEXT("DestroyedWorld: %s"), *World->GetFName().ToString());
			}
		});
	}


	CreatedWorlds.Add(NewWorld);

	World = NewWorld;


}

Seems someone already wrote a plugin to handle this. Might be of interest to you

I managed to get ahead a little. I was able to move between the created world and then back. The problem is that in the Standalone game, recreating UWorld causes the editor to crash. I don’t know what could be the problem, can anyone help me?

.h

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

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "GameBFL.generated.h"





USTRUCT(BlueprintType)
struct FUWorldContext
{
	GENERATED_BODY()
public:
	//~ The following member variable will be accessible by Blueprint Graphs:
	// This is the tooltip for our test variable.


	//~ The following member variable will be not accessible by Blueprint Graphs:
	int32 NativeOnlyMemberVariable;

	/**~
	* This UObject pointer is not accessible to Blueprint Graphs, but
	* is visible to UE4's reflection, smart pointer, and garbage collection
	* systems.
	*/
	UPROPERTY()
		UObject* SafeObjectPointer;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Test Variables")
		UWorld* ContextWorld;

private:
	//FWorldContext* WorldContext;


public:
	void SetWorldContext(FWorldContext* inContext) { ContextWorld = inContext->World(); }



};













/**
 * 
 */
UCLASS()
class GAMEPROJECT_API UGameBFL : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

public:


	UFUNCTION(BlueprintCallable)
		static TArray<uint8> SaveToBinaryArray(UObject* Object, bool IsSaveGameOnly);
	UFUNCTION(BlueprintCallable)
		static void LoadFromBinaryArray(TArray<uint8> SaveData, UObject* Object, bool IsSaveGameOnly);





	UFUNCTION(BlueprintCallable)
		static void CreateNavigationData(UObject* World);
	UFUNCTION(BlueprintCallable)
		static void BuildNavigation(UObject* World);

	UFUNCTION(BlueprintCallable)
		static TArray<uint8> SaveNavData(UObject* World);
	UFUNCTION(BlueprintCallable)
		static void LoadNavData(UObject* World, TArray<uint8> data);



	//UWorlds ==============================================================================================================
	UFUNCTION(BlueprintCallable, meta = (WorldContextObject = "WorldContextObject"))
		static void CreateNewWorld_OLD(const UObject* WorldContextObject, FString LevelName, const TSoftObjectPtr<UWorld> Level, UWorld*& World);


	static UWorld* CreateWorld(const EWorldType::Type InWorldType, bool bInformEngineOfWorld, FName WorldName = NAME_None, UPackage* InWorldPackage = NULL, bool bAddToRoot = true, ERHIFeatureLevel::Type InFeatureLevel = ERHIFeatureLevel::Num);




	UFUNCTION(BlueprintCallable, meta = (WorldContextObject = "WorldContextObject"))
		static void CreateNewWorld2_OLD(const UObject* WorldContextObject, const TSoftObjectPtr<UWorld> Level, FUWorldContext& UWorldContext);

	UFUNCTION(BlueprintCallable)
		static void CreateNewWorld3(const TSoftObjectPtr<UWorld> Level, const TSubclassOf<class AGameModeBase> GameMode, FUWorldContext& UWorldContext);



	UFUNCTION(BlueprintCallable, meta = (WorldContextObject = "WorldContextObject"))
		static void DestroyCreatedWorld(FUWorldContext UWorldContext);


	static TMap<UWorld*,FDelegateHandle> CleanupHandles;
	static FDelegateHandle CleanupHandle;
	static TMap<UWorld*, FDelegateHandle> TickHandles;
	static FDelegateHandle TickHandle;
	static TArray<UWorld*> CreatedWorlds;

	UFUNCTION(BlueprintCallable)
		static void WorldBeginPlay(UObject* World);


	UFUNCTION(BlueprintPure)
		static UWorld* GetMainWorld();
	UFUNCTION(BlueprintPure)
		static FUWorldContext GetMainWorldContext();
	//UWorlds end ==========================================================================================================
	//UWorlds switch world side ===========================================================================================
	UFUNCTION(BlueprintCallable)
		static APlayerController* FindPCInWorlds();
	UFUNCTION(BlueprintCallable)
		static APlayerController* ChangeWorld(FUWorldContext UWorldContext, APawn*& PrevPawn);
	/*UFUNCTION(BlueprintCallable)
		static APlayerController* FindPCInWorlds(UObject* World);*/
	//UWorlds switch world side end =======================================================================================

	UFUNCTION(BlueprintCallable)
		static void ProcessTick(TArray<UObject*> Objects, float DeltaSeconds);



	UFUNCTION(BlueprintCallable, meta = (DeterminesOutputType = "InputActor"))
		static AActor* CloneActor(const UObject* WorldContextObject, AActor* InputActor, FTransform Transform);

	UFUNCTION(BlueprintCallable)
		static void RerunConstructionScripts(AActor* Actor);

	//UFUNCTION(BlueprintCallable)
	//	AActor* SpawnActorForLoad(const UObject* WorldContextObject, UClass* Class, FTransform const* Transform, AActor* Owner, APawn* Instigator);

	 /**
 * Renders a widget to a Render Texture 2D with the given draw size.
 *
 * @param widget      The widget to converted to a Render Texture 2D.
 * @param drawSize    The size to render the Widget to. Also will be the texture size.
 * @return            The texture render target 2D containing the rendered widget.
 */
	UFUNCTION(BlueprintCallable)
		static UTextureRenderTarget2D* WidgetToTexture(UUserWidget* const widget, const FVector2D& drawSize);


	/**
*Renders a UMG Widget to a texture with the specified size.
*
* @param Widget        The widget to be rendered.
* @param DrawSize    The size to render the Widget to.Also will be the texture size.
* @return            The texture containing the rendered widget.
*/
	UFUNCTION(BlueprintCallable)
		static UTexture2D* TextureFromWidget(UUserWidget* const Widget, const FVector2D& DrawSize);


	UFUNCTION(BlueprintCallable)
		static void PressAnyKey(FKey Key);
	UFUNCTION(BlueprintCallable)
		static void ReleaseAnyKey(FKey Key);

	UFUNCTION(BlueprintCallable)
		static void GetDerivedClassesOfClass(const UClass* ClassToLookFor, TArray< UClass* >& Results, bool bRecursive);

};

.cpp

#include "GameBFL.h"

#include "Serialization/ObjectAndNameAsStringProxyArchive.h"

#include "EngineUtils.h"
#include "Kismet/GameplayStatics.h"
#include "GameFramework/GameModeBase.h"

#include "NavigationSystem.h"
#include "NavMesh/RecastNavMesh.h"

#include "UObject/UObjectHash.h"

#include "GameFramework/PlayerController.h"



TMap<UWorld*, FDelegateHandle> UGameBFL::CleanupHandles;
FDelegateHandle UGameBFL::CleanupHandle;
TMap<UWorld*, FDelegateHandle> UGameBFL::TickHandles;
FDelegateHandle UGameBFL::TickHandle;
TArray<UWorld*> UGameBFL::CreatedWorlds;


FUWorldContext UGameBFL::GetMainWorldContext()
{
	FUWorldContext UWorldContext;
	UWorldContext.ContextWorld = GEngine->GetCurrentPlayWorld();
	return UWorldContext;
}


UWorld* UGameBFL::GetMainWorld()
{
	return GEngine->GetCurrentPlayWorld();
}

APlayerController* UGameBFL::FindPCInWorlds()
{
	//GEngine->GameViewport->Viewport;
	//GetGameViewport()->bDisableWorldRendering;
	//WorldContext->GameViewport;

	//auto OldWorld = Cast<UWorld>(World);
	//return OldWorld->GetFirstPlayerController();

	APlayerController* PC = nullptr;
	PC = GetMainWorld()->GetFirstPlayerController();

	if (!PC) {
		for (auto CurWorld : CreatedWorlds)
		{
			PC = CurWorld->GetFirstPlayerController();
			if (PC) break;
		}
	}
	return PC ? PC : nullptr;
}


APlayerController* UGameBFL::ChangeWorld(FUWorldContext UWorldContext, APawn*& PrevPawn) {


	//auto NewWorld = ToWorld;
	auto NewWorld = UWorldContext.ContextWorld;
	//if (ToWorld) NewWorld = ToWorld;
	if (!IsValid(NewWorld)) return nullptr;
	auto WorldContext = GEngine->GetWorldContextFromWorld(NewWorld);

	auto GameInstance = UGameplayStatics::GetGameInstance(GetMainWorld());
	//auto context = GameInstance->GetWorldContext()->GameViewport;

	//switch render to new UWorld
	NewWorld->GetGameViewport()->Init(*WorldContext, GameInstance);




	//find PC in worlds
	APlayerController* PC = nullptr;

	PC = GetMainWorld()->GetFirstPlayerController();

	if (!PC) {
		for (auto CurWorld : CreatedWorlds)
		{
			PC = CurWorld->GetFirstPlayerController();
			if (PC) break;
		}
	}


	if (PC) PrevPawn = PC->GetPawn();



	return PC ? PC : nullptr;

}



//void UGameBFL::CreateNewWorld3(const UObject* WorldContextObject, const TSoftObjectPtr<UWorld> Level, UWorld*& World, FUWorldContext& UWorldContext)
void UGameBFL::CreateNewWorld3(const TSoftObjectPtr<UWorld> Level, TSubclassOf<class AGameModeBase> GameMode, FUWorldContext& UWorldContext)
{

	UWorld* NewWorld = nullptr;

	const FString LevelName2 = FPackageName::ObjectPathToPackageName(Level.ToString());
	//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("level name = %s"), *LevelName2));

	UPackage* WorldPackage = FindPackage(nullptr, *LevelName2);
	if (WorldPackage == nullptr)
	{
		WorldPackage = LoadPackage(nullptr, *LevelName2, ELoadFlags::LOAD_None);
		if (!WorldPackage)
		{
			GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Package not loaded")));
			return;
		}

	}

	///======

	if (!WorldPackage)
	{
		WorldPackage = CreatePackage(nullptr);
	}

	//if (InWorldType == EWorldType::PIE)
	//{
	//	WorldPackage->SetPackageFlags(PKG_PlayInEditor);
	//}

	// Mark the package as containing a world.  This has to happen here rather than at serialization time,
	// so that e.g. the referenced assets browser will work correctly.
	if (WorldPackage != GetTransientPackage())
	{
		WorldPackage->ThisContainsMap();
	}
	///======


	UPackage* NewWorldPackage = CreatePackage(nullptr);
	NewWorldPackage->SetPackageFlags(PKG_PlayInEditor);
	NewWorldPackage->PIEInstanceID = WorldPackage->GetPIEInstanceID();
	NewWorldPackage->FileName = FName(*WorldPackage->GetName());
	NewWorldPackage->SetGuid(WorldPackage->GetGuid());
	NewWorldPackage->MarkAsFullyLoaded();


	UWorld* PackageWorld = UWorld::FindWorldInPackage(WorldPackage);



	FObjectDuplicationParameters Parameters(PackageWorld, NewWorldPackage);
	//Parameters.DestName = PackageWorld->GetFName();
	Parameters.DestName = FName();
	Parameters.DestClass = PackageWorld->GetClass();
	Parameters.DuplicateMode = EDuplicateMode::PIE;
	Parameters.PortFlags = EPropertyPortFlags::PPF_Duplicate;

	NewWorld = CastChecked<UWorld>(StaticDuplicateObjectEx(Parameters));

	//NewWorld = UWorld::DuplicateWorldForPIE(LevelName2, PackageWorld);
	//if (!NewWorld)
	//{
	//	return;
	//}


	//const FString WorldNameString = "CreatedMap" + FString::FromInt(FMath::RandRange(0, 100));
	//NewWorld = UWorld::CreateWorld(EWorldType::PIE, true, FName(*WorldNameString));
	//NewWorld = UWorld::CreateWorld(EWorldType::Game, true, FName("CreatedMap"), WorldPackage);










	NewWorld->SetShouldTick(true);


	FWorldContext& WorldContext = GEngine->CreateNewWorldContext(EWorldType::Game);
	//WorldContext.OwningGameInstance = UGameplayStatics::GetGameInstance(WorldContextObject);
	WorldContext.OwningGameInstance = UGameplayStatics::GetGameInstance(GEngine->GetCurrentPlayWorld());
	//WorldContext.PIEInstance = -1;
	NewWorld->SetGameInstance(UGameplayStatics::GetGameInstance(GEngine->GetCurrentPlayWorld()));
	////NewWorld->WorldType = WorldContext.WorldType;
	NewWorld->WorldType = EWorldType::PIE;
	WorldContext.SetCurrentWorld(NewWorld);


	auto GameInstance = UGameplayStatics::GetGameInstance(GetMainWorld());
	auto context = GameInstance->GetWorldContext()->GameViewport;
	//ViewportClient->Init(*GameInstance->GetWorldContext(), GameInstance);
	WorldContext.GameViewport = context;



	//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("CreateWorld: %s"), *NewWorld->GetFName().ToString()));

	//// In the PIE case the world will already have been initialized as part of CreatePIEWorldByDuplication
	if (!WorldContext.World()->bIsWorldInitialized)
	{
		WorldContext.World()->InitWorld();
	}

	/*FNavigationSystemRunMode ResolvedRunMode(FNavigationSystemRunMode::GameMode);
	switch (NewWorld->WorldType)
	{
	case EWorldType::Editor:
	case EWorldType::EditorPreview:
		ResolvedRunMode = FNavigationSystemRunMode::EditorMode;
		break;

	case EWorldType::PIE:
		ResolvedRunMode = FNavigationSystemRunMode::PIEMode;
		break;

	case EWorldType::Game:
	case EWorldType::GamePreview:
	case EWorldType::GameRPC:
		ResolvedRunMode = FNavigationSystemRunMode::GameMode;
		break;

	case EWorldType::Inactive:
	case EWorldType::None:
		ResolvedRunMode = FNavigationSystemRunMode::InvalidMode;
		break;

	default:
		UE_LOG(LogNavigation, Warning, TEXT("%s Unhandled world type, defaulting to FNavigationSystemRunMode::InvalidMode."), ANSI_TO_TCHAR(__FUNCTION__));
		ResolvedRunMode = FNavigationSystemRunMode::InvalidMode;
	}

	if (NewWorld->GetNavigationSystem())
	{
		NewWorld->GetNavigationSystem()->InitializeForWorld(*NewWorld, ResolvedRunMode);
	}*/
	//else if (ResolvedRunMode == FNavigationSystemRunMode::EditorMode)
	//{
	//	DiscardNavigationDataChunks(WorldOwner);
	//}



	FURL URL;
	//FURL URL(&WorldContext.LastURL, *NewWorld->GetFName().ToString(), ETravelType::TRAVEL_Absolute);
	FString GamemodePath = FString("GAME=") + GameMode->GetPathName();
	//URL.AddOption(TEXT("GAME=/Game/Blueprints/GameModeBP_CreatedWorld.GameModeBP_CreatedWorld_C"));
	const TCHAR* GMPath = *GamemodePath;
	URL.AddOption(GMPath);
	WorldContext.World()->SetGameMode(URL);


	//WorldContext.World()->CreateAISystem();





	WorldContext.World()->InitializeActorsForPlay(URL);



	//AActor* lacder = nullptr;

	for (auto actor : NewWorld->PersistentLevel->Actors) {
		UE_LOG(LogTemp, Warning, TEXT("LoadedWorldActorsClasses: %s"), *UKismetSystemLibrary::GetDisplayName(actor));
		//if (actor->GetClass()->GetName() == "BpGameMode2_C")
		//{
		//	//lacder = actor;
		//}
	}
	UFunction* Func = NewWorld->GetAuthGameMode()->GetClass()->FindFunctionByName(FName("Load"));
	if (Func == nullptr) {
		return;
	}
	FStructOnScope FuncParam(Func);
	NewWorld->GetAuthGameMode()->ProcessEvent(Func, FuncParam.GetStructMemory());




	//UNavigationSystemV1 *NavSys = FNavigationSystem::GetCurrent<UNavigationSystemV1>(NewWorld);
	//if (NavSys)
	//{
	//	ANavigationData *UseNavData = NavSys->GetDefaultNavDataInstance(FNavigationSystem::Create);
	//	NavSys->Build();
	//}


	WorldContext.World()->BeginPlay();
	WorldContext.World()->bWorldWasLoadedThisTick = true;




	//if (!CleanupHandle.IsValid()) {

		// Tick call in PIE
	auto TickHandle2 = FWorldDelegates::OnWorldTickStart.AddLambda([NewWorld](UWorld* World, ELevelTick TickType, float DeltaSeconds) {
		if (World == GetMainWorld() && GetMainWorld()->WorldType == EWorldType::PIE) {
			auto TickHand = TickHandles.Find(NewWorld);
			if (TickHand->IsValid()) {
				if (NewWorld->ShouldTick())
				{
					NewWorld->Tick(TickType, DeltaSeconds);
					//GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Yellow, FString::Printf(TEXT("TickInWorld: %s"), *NewWorld->GetFName().ToString()));
					//UE_LOG(LogTemp, Warning, TEXT("TickInWorld: %s"), *NewWorld->GetFName().ToString());
				}

			}
		}});
		if (TickHandle.IsValid())
		{
			GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Yellow, FString::Printf(TEXT("TickHackSet")));
			UE_LOG(LogTemp, Warning, TEXT("TickHackSet"));
		}
		TickHandles.Add(NewWorld, TickHandle2);


		auto CHandle = FWorldDelegates::OnPostWorldCleanup.AddLambda([NewWorld](UWorld* World, bool bSessionEnded, bool bCleanupResources) {
			if (!CreatedWorlds.Contains(World)) {;
				auto CLHandle = CleanupHandles.Find(NewWorld);
				if (CLHandle) {
					FWorldDelegates::OnPostWorldCleanup.Remove(*CLHandle);
					CLHandle->Reset();
					CleanupHandles.Remove(NewWorld);
				}
				auto TickHand = TickHandles.Find(NewWorld);
				if (TickHand && TickHand->IsValid()) {
					FWorldDelegates::OnWorldTickStart.Remove(*TickHand);
					TickHand->Reset();
					TickHandles.Remove(NewWorld);
				}

				
				if (NewWorld) {
					auto Name = NewWorld->GetMapName();
					for (FActorIterator ActorIt(NewWorld); ActorIt; ++ActorIt)
					{
						//ActorIt->RouteEndPlay(EEndPlayReason::LevelTransition);
						ActorIt->Destroy();
					}

					// Do this after destroying pawns/playercontrollers, in case that spawns new things (e.g. dropped weapons)
					//WorldRef->CleanupWorld();

					//GEngine->WorldDestroyed(WorldRef);

					CreatedWorlds.Remove(NewWorld);

					GEngine->DestroyWorldContext(NewWorld);
					NewWorld->DestroyWorld(true);

					GEngine->TrimMemory();
					//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Created World destroyed: %s"), *WorldRef->GetFName().ToString()));
					UE_LOG(LogTemp, Warning, TEXT("Created World destroyed: %s"), *Name);

				}
			

				//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("DestroyedWorld: %s"), *World->GetFName().ToString()));
				UE_LOG(LogTemp, Warning, TEXT("DestroyedWorld: %s"), *World->GetFName().ToString());
			}
			});
		CleanupHandles.Add(NewWorld, CHandle);
	//}


	CreatedWorlds.Add(NewWorld);

	UWorldContext.SetWorldContext(&WorldContext);
	//World = NewWorld;
	//
	//
	//auto vp = World->GetGameViewport();
	//if (vp) {
	//	GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Exist viewport")));
	//	//World->GetGameViewport()->Init(WorldContext, GameInstance);
	//	GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Player: %d"), World->GetAuthGameMode()->GetNumPlayers()));
	//
	//}
	//else
	//{
	//	GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("No viewport")));
	//}

	//GEngine->GameViewport->Viewport->;
	//FViewportClient* Client = GEngine->GameViewport->Viewport->GetClient();
	//Client->
	//FViewport::SetViewportClient;

}







void UGameBFL::DestroyCreatedWorld(FUWorldContext UWorldContext) {

	//auto WorldRef = Cast<UWorld>(World->GetWorld());
	auto WorldRef = UWorldContext.ContextWorld;

	//WorldRef->SetShouldTick(false);

	if (CreatedWorlds.Contains(WorldRef)) {
		/*auto CleanDelegat = CleanupHandles.Find(WorldRef);
		if (CleanDelegat->IsValid()) {
			FWorldDelegates::OnPostWorldCleanup.Remove(*CleanDelegat);
			CleanDelegat->Reset();
		}*/
		auto TickHand = TickHandles.Find(WorldRef);
		if (TickHand && TickHand->IsValid()) {
			FWorldDelegates::OnWorldTickStart.Remove(*TickHand);
			TickHand->Reset();
			TickHandles.Remove(WorldRef);
		}
		CreatedWorlds.Remove(WorldRef);
	}

	if (WorldRef) {
		auto WorldName = WorldRef->GetMapName();
		WorldRef->DestroyWorld(true);

		WorldRef->MarkAsGarbage();
		UE_LOG(LogTemp, Warning, TEXT("Destroy UWorld from player event: %s"), *WorldName);
		}
	
	//if (WorldRef)
	//{
	//	
	//	auto WorldName = WorldRef->GetMapName();
	//	for (FActorIterator ActorIt(WorldRef); ActorIt; ++ActorIt)
	//	{
	//		
	//		//ActorIt->RouteEndPlay(EEndPlayReason::LevelTransition);
	//		ActorIt->Destroy();
	//	}

	//	// Do this after destroying pawns/playercontrollers, in case that spawns new things (e.g. dropped weapons)
	//	//WorldRef->CleanupWorld();
	//	

	//	//GEngine->DestroyWorldContext(WorldRef);

	//	GEngine->WorldDestroyed(WorldRef);


	//	WorldRef->DestroyWorld(true);
	//

	//	GEngine->TrimMemory();
	//	//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Created World destroyed: %s"), *WorldRef->GetFName().ToString()));
	//	UE_LOG(LogTemp, Warning, TEXT("Destroy from player event: %s"), *WorldName);
	//}

}



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////				World old						 //////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



void UGameBFL::CreateNewWorld2_OLD(const UObject* WorldContextObject, const TSoftObjectPtr<UWorld> Level, FUWorldContext& UWorldContext)
{

	UWorld* NewWorld = nullptr;

	const FString LevelName2 = FPackageName::ObjectPathToPackageName(Level.ToString());
	//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("level name = %s"), *LevelName2));

	UPackage* WorldPackage = FindPackage(nullptr, *LevelName2);
	if (WorldPackage == nullptr)
	{
		WorldPackage = LoadPackage(nullptr, *LevelName2, ELoadFlags::LOAD_None);
		if (!WorldPackage)
		{
			GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Package not loaded")));
			return;
		}

	}


	UWorld* PackageWorld = UWorld::FindWorldInPackage(WorldPackage);



	UPackage* NewWorldPackage = CreatePackage(nullptr);
	//NewWorldPackage->SetPackageFlags(PKG_PlayInEditor);
	//NewWorldPackage->PIEInstanceID = PIEInstanceID;
	//NewWorldPackage->FileName = PackageFName;
	//NewWorldPackage->SetGuid(EditorLevelPackage->GetGuid());
	//NewWorldPackage->MarkAsFullyLoaded();


	FObjectDuplicationParameters Parameters(PackageWorld, NewWorldPackage);
	Parameters.DestName = PackageWorld->GetFName();
	Parameters.DestClass = PackageWorld->GetClass();
	Parameters.DuplicateMode = EDuplicateMode::PIE;
	Parameters.PortFlags = EPropertyPortFlags::PPF_Duplicate;

	NewWorld = CastChecked<UWorld>(StaticDuplicateObjectEx(Parameters));

	//NewWorld = UWorld::DuplicateWorldForPIE(LevelName2, PackageWorld);
	//if (!NewWorld)
	//{
	//	return;
	//}


	//const FString WorldNameString = "CreatedMap" + FString::FromInt(FMath::RandRange(0, 100));
	//NewWorld = UWorld::CreateWorld(EWorldType::PIE, true, FName(*WorldNameString));
	//NewWorld = UWorld::CreateWorld(EWorldType::Game, true, FName("CreatedMap"), WorldPackage);


	NewWorld->SetShouldTick(true);


	FWorldContext& WorldContext = GEngine->CreateNewWorldContext(EWorldType::Game);
	WorldContext.OwningGameInstance = UGameplayStatics::GetGameInstance(WorldContextObject);
	//WorldContext.PIEInstance = -1;
	NewWorld->SetGameInstance(UGameplayStatics::GetGameInstance(WorldContextObject));
	////NewWorld->WorldType = WorldContext.WorldType;
	NewWorld->WorldType = EWorldType::PIE;
	WorldContext.SetCurrentWorld(NewWorld);

	
	auto GameInstance = UGameplayStatics::GetGameInstance(GetMainWorld());
	auto context = GameInstance->GetWorldContext()->GameViewport;
	//ViewportClient->Init(*GameInstance->GetWorldContext(), GameInstance);
	WorldContext.GameViewport = context;



	//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("CreateWorld: %s"), *NewWorld->GetFName().ToString()));

	//// In the PIE case the world will already have been initialized as part of CreatePIEWorldByDuplication
	if (!WorldContext.World()->bIsWorldInitialized)
	{
		WorldContext.World()->InitWorld();
	}

	/*FNavigationSystemRunMode ResolvedRunMode(FNavigationSystemRunMode::GameMode);
	switch (NewWorld->WorldType)
	{
	case EWorldType::Editor:
	case EWorldType::EditorPreview:
		ResolvedRunMode = FNavigationSystemRunMode::EditorMode;
		break;

	case EWorldType::PIE:
		ResolvedRunMode = FNavigationSystemRunMode::PIEMode;
		break;

	case EWorldType::Game:
	case EWorldType::GamePreview:
	case EWorldType::GameRPC:
		ResolvedRunMode = FNavigationSystemRunMode::GameMode;
		break;

	case EWorldType::Inactive:
	case EWorldType::None:
		ResolvedRunMode = FNavigationSystemRunMode::InvalidMode;
		break;

	default:
		UE_LOG(LogNavigation, Warning, TEXT("%s Unhandled world type, defaulting to FNavigationSystemRunMode::InvalidMode."), ANSI_TO_TCHAR(__FUNCTION__));
		ResolvedRunMode = FNavigationSystemRunMode::InvalidMode;
	}

	if (NewWorld->GetNavigationSystem())
	{
		NewWorld->GetNavigationSystem()->InitializeForWorld(*NewWorld, ResolvedRunMode);
	}*/
	//else if (ResolvedRunMode == FNavigationSystemRunMode::EditorMode)
	//{
	//	DiscardNavigationDataChunks(WorldOwner);
	//}



	FURL URL;
	//FURL URL(&WorldContext.LastURL, *NewWorld->GetFName().ToString(), ETravelType::TRAVEL_Absolute);
	//URL.AddOption(TEXT("GAME=/Game/ThirdPersonCPP/Blueprints/BpGameMode2.BpGameMode2_C"));
	URL.AddOption(TEXT("GAME=/Game/Blueprints/GameModeBP_CreatedWorld.GameModeBP_CreatedWorld_C"));
	WorldContext.World()->SetGameMode(URL);


	//WorldContext.World()->CreateAISystem();





	WorldContext.World()->InitializeActorsForPlay(URL);



	//AActor* lacder = nullptr;

	for (auto actor : NewWorld->PersistentLevel->Actors) {
		UE_LOG(LogTemp, Warning, TEXT("LoadedWorldActorsClasses: %s"), *UKismetSystemLibrary::GetDisplayName(actor));
		//if (actor->GetClass()->GetName() == "BpGameMode2_C")
		//{
		//	//lacder = actor;
		//}
	}
	UFunction* Func = NewWorld->GetAuthGameMode()->GetClass()->FindFunctionByName(FName("Load"));
	if (Func == nullptr) {
		return;
	}
	FStructOnScope FuncParam(Func);
	NewWorld->GetAuthGameMode()->ProcessEvent(Func, FuncParam.GetStructMemory());




	//UNavigationSystemV1 *NavSys = FNavigationSystem::GetCurrent<UNavigationSystemV1>(NewWorld);
	//if (NavSys)
	//{
	//	ANavigationData *UseNavData = NavSys->GetDefaultNavDataInstance(FNavigationSystem::Create);
	//	NavSys->Build();
	//}

	
	WorldContext.World()->BeginPlay();
	WorldContext.World()->bWorldWasLoadedThisTick = true;




	if (!CleanupHandle.IsValid()) {

		// Tick call in PIE
		TickHandle = FWorldDelegates::OnWorldTickStart.AddLambda([](UWorld* World, ELevelTick TickType, float DeltaSeconds) {
			if (World == GetMainWorld() && GetMainWorld()->WorldType == EWorldType::PIE) {
				for (auto WorldRef : CreatedWorlds) {
					if (WorldRef->ShouldTick())
					{
						WorldRef->Tick(TickType, DeltaSeconds);
						//GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Yellow, FString::Printf(TEXT("TickInWorld: %s"), *WorldRef->GetFName().ToString()));
						//UE_LOG(LogTemp, Warning, TEXT("TickInWorld: %s"), *WorldRef->GetFName().ToString());
					}
				}
			}
		});
		if (TickHandle.IsValid())
		{
			GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Yellow, FString::Printf(TEXT("TickHackSet")));
			UE_LOG(LogTemp, Warning, TEXT("TickHackSet"));
		}

		CleanupHandle = FWorldDelegates::OnPostWorldCleanup.AddLambda([](UWorld *World, bool bSessionEnded, bool bCleanupResources) {
			if (!CreatedWorlds.Contains(World)) {
				FWorldDelegates::OnPostWorldCleanup.Remove(CleanupHandle);
				CleanupHandle.Reset();
				if (TickHandle.IsValid()) {
					FWorldDelegates::OnWorldTickStart.Remove(TickHandle);
					TickHandle.Reset();
				}

				for (auto WorldRef : CreatedWorlds) {
					if (WorldRef) {
						auto Name = WorldRef->GetMapName();
						for (FActorIterator ActorIt(WorldRef); ActorIt; ++ActorIt)
						{
							ActorIt->RouteEndPlay(EEndPlayReason::LevelTransition);
						}

						// Do this after destroying pawns/playercontrollers, in case that spawns new things (e.g. dropped weapons)
						//WorldRef->CleanupWorld();

						//GEngine->WorldDestroyed(WorldRef);



						GEngine->DestroyWorldContext(WorldRef);
						WorldRef->DestroyWorld(true);

						GEngine->TrimMemory();
						//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Created World destroyed: %s"), *WorldRef->GetFName().ToString()));
						UE_LOG(LogTemp, Warning, TEXT("Created World destroyed: %s"), *Name);
					}
				}
				CreatedWorlds.Empty();

				//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("DestroyedWorld: %s"), *World->GetFName().ToString()));
				UE_LOG(LogTemp, Warning, TEXT("DestroyedWorld: %s"), *World->GetFName().ToString());
			}
		});
	}


	CreatedWorlds.Add(NewWorld);

	UWorldContext.SetWorldContext(&WorldContext);
	////World = NewWorld;
	//UWorldContext.SetWorldContext(&WorldContext);
	//
	//auto vp = World->GetGameViewport();
	//if (vp) {
	//	GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Exist viewport")));
	//	//World->GetGameViewport()->Init(WorldContext, GameInstance);
	//	GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Player: %d"), World->GetAuthGameMode()->GetNumPlayers()));

	//}
	//else
	//{
	//	GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("No viewport")));
	//}

	//GEngine->GameViewport->Viewport->;
	FViewportClient* Client = GEngine->GameViewport->Viewport->GetClient();
	//Client->
	//FViewport::SetViewportClient;

}




void UGameBFL::CreateNewWorld_OLD(const UObject* WorldContextObject, FString LevelName, const TSoftObjectPtr<UWorld> Level, UWorld*& World)
{
//
//	UWorld* NewWorld = nullptr;
//
//
//
//	{
//		const FString LevelName2 = FPackageName::ObjectPathToPackageName(FString("/Game/Maps/TetsMultiWorld/CharacterViewLevel.CharacterViewLevel"));	//"/Game/ThirdPersonCPP/Maps/Map3"
//		//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("level name = %s"), *LevelName2));
//
//		UPackage* WorldPackage = FindPackage(nullptr, *LevelName2);
//		if (WorldPackage == nullptr)
//		{
//			WorldPackage = LoadPackage(nullptr, *LevelName2, ELoadFlags::LOAD_None);
//			if (!WorldPackage)
//			{
//				GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Package not loaded")));
//				return;
//			}
//
//		}
//
//		UWorld* PackageWorld = UWorld::FindWorldInPackage(WorldPackage);
//
//		for (auto actor : PackageWorld->PersistentLevel->Actors) {
//			UE_LOG(LogTemp, Warning, TEXT("DestroyedWorld: %s"), *actor->GetClass()->GetName());
//
//		}
//
//
//	}
//
//
//
//	// Create new UWorld, ULevel and UModel.
//	//const FString WorldNameString = (!LevelName.IsEmpty()) ? LevelName2 : TEXT("Untitled");
//	//NewWorld = NewObject<UWorld>(WorldPackage, *WorldNameString);
//	//NewWorld->SetFlags(RF_Transactional);
//	//NewWorld->FeatureLevel = ERHIFeatureLevel::Num;
//
//
//	//NewWorld = UWorld::CreateWorld(EWorldType::PIE, true, FName(*LevelName));
//	NewWorld = CreateWorld(EWorldType::PIE, true, FName(*LevelName));
//
//
//
//
//
//
//	//Enable tick?????????
//	NewWorld->SetShouldTick(true);
//	
//	FWorldContext& WorldContext = GEngine->CreateNewWorldContext(EWorldType::Game);
//	WorldContext.OwningGameInstance = UGameplayStatics::GetGameInstance(WorldContextObject);
//	WorldContext.SetCurrentWorld(NewWorld);
//
//	WorldContext.World()->SetGameInstance(WorldContext.OwningGameInstance);
//
//	//NewWorld->WorldType = WorldContext.WorldType;
//
//
//
//	//// In the PIE case the world will already have been initialized as part of CreatePIEWorldByDuplication
//	if (!WorldContext.World()->bIsWorldInitialized)
//	{
//		WorldContext.World()->InitWorld();
//	}
//
//
//
//	FURL URL;
//	//FURL URL(&WorldContext.LastURL, *NewWorld->GetFName().ToString(), ETravelType::TRAVEL_Absolute);
//	//URL.AddOption(TEXT("GAME=/Game/ThirdPersonCPP/Blueprints/BpGameMode2.BpGameMode2_C"));
//	URL.AddOption(TEXT("GAME=/Game/Blueprints/GameModeBP_CreatedWorld.GameModeBP_CreatedWorld_C"));
//	WorldContext.World()->SetGameMode(URL);
//
//
//	//WorldContext.World()->CreateAISystem();
//
//
//
//
//
//	WorldContext.World()->InitializeActorsForPlay(URL);
//
//	for (auto actor : NewWorld->PersistentLevel->Actors) {
//		UE_LOG(LogTemp, Warning, TEXT("LoadedWorldActorsClasses: %s"), *UKismetSystemLibrary::GetDisplayName(actor));
//		//if (actor->GetClass()->GetName() == "BpGameMode2_C")
//		//{
//		//	//lacder = actor;
//		//}
//	}
//
//
//
//	WorldContext.World()->BeginPlay();
//	WorldContext.World()->bWorldWasLoadedThisTick = true;
//
//
//
//	if (!CleanupHandle.IsValid()) {
//
//		// Tick call in PIE
//		FWorldDelegates::OnWorldTickStart.AddLambda([](UWorld* World, ELevelTick TickType, float DeltaSeconds) {
//			if (World == GetMainWorld() && GetMainWorld()->WorldType == EWorldType::PIE) {
//				for (auto WorldRef : CreatedWorlds) {
//					if (WorldRef == World && World->ShouldTick()) {
//						WorldRef->Tick(TickType, DeltaSeconds);
//						//GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Yellow, FString::Printf(TEXT("TickInWorld: %s"), *WorldRef->GetFName().ToString()));
//						//UE_LOG(LogTemp, Warning, TEXT("TickInWorld: %s"), *WorldRef->GetFName().ToString());
//					}
//				}
//			}
//		});
//
//
//		CleanupHandle = FWorldDelegates::OnPostWorldCleanup.AddLambda([](UWorld* World, bool bSessionEnded, bool bCleanupResources) {
//			if (!CreatedWorlds.Contains(World)) {
//				FWorldDelegates::OnPostWorldCleanup.Remove(CleanupHandle);
//				CleanupHandle.Reset();
//
//				for (auto WorldRef : CreatedWorlds) {
//					auto Name = WorldRef->GetMapName();
//					for (FActorIterator ActorIt(WorldRef); ActorIt; ++ActorIt)
//					{
//						ActorIt->RouteEndPlay(EEndPlayReason::LevelTransition);
//					}
//
//					// Do this after destroying pawns/playercontrollers, in case that spawns new things (e.g. dropped weapons)
//					//WorldRef->CleanupWorld();
//
//					//GEngine->WorldDestroyed(WorldRef);
//
//
//
//					GEngine->DestroyWorldContext(WorldRef);
//					WorldRef->DestroyWorld(true);
//
//					GEngine->TrimMemory();
//					//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Created World destroyed: %s"), *WorldRef->GetFName().ToString()));
//					UE_LOG(LogTemp, Warning, TEXT("Created World destroyed: %s"), *Name);
//				}
//				CreatedWorlds.Empty();
//
//				//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("DestroyedWorld: %s"), *World->GetFName().ToString()));
//				UE_LOG(LogTemp, Warning, TEXT("DestroyedWorld: %s"), *World->GetFName().ToString());
//			}
//		});
//	}
//
//
//	CreatedWorlds.Add(NewWorld);
//	World = NewWorld;
//
//
//	
//
//
//	//FTimerDelegate TimerCallback;
//	//TimerCallback.BindLambda([WorldContext, NewWorld]
//	//{
//	//	for (FActorIterator ActorIt(WorldContext.World()); ActorIt; ++ActorIt)
//	//	{
//	//		ActorIt->RouteEndPlay(EEndPlayReason::LevelTransition);
//	//	}
//
//	//	// Do this after destroying pawns/playercontrollers, in case that spawns new things (e.g. dropped weapons)
//	//	WorldContext.World()->CleanupWorld();
//
//	//	GEngine->WorldDestroyed(WorldContext.World());
//
//	//	GEngine->DestroyWorldContext(NewWorld);
//	//	NewWorld->DestroyWorld(true);
//
//	//	GEngine->TrimMemory();
//	//	GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("World unloaded")));
//	//});
//
//	//FTimerHandle Handle;
//	//WorldContextObject->GetWorld()->GetTimerManager().SetTimer(Handle, TimerCallback, 5.0f, false);
//
//
//
//
//
//
}





void UGameBFL::WorldBeginPlay(UObject* World)
{
	auto NewWorld = Cast<UWorld>(World->GetWorld());
	if (NewWorld)
	{
		NewWorld->BeginPlay();
	}

}


UWorld* UGameBFL::CreateWorld(const EWorldType::Type InWorldType, bool bInformEngineOfWorld, FName WorldName, UPackage* InWorldPackage, bool bAddToRoot, ERHIFeatureLevel::Type InFeatureLevel)
{
	if (InFeatureLevel >= ERHIFeatureLevel::Num)
	{
		InFeatureLevel = ERHIFeatureLevel::SM5;
	}

	UPackage* WorldPackage = InWorldPackage;
	if (!WorldPackage)
	{
		WorldPackage = CreatePackage(nullptr);
	}

	if (InWorldType == EWorldType::PIE)
	{
		WorldPackage->SetPackageFlags(PKG_PlayInEditor);
	}

	// Mark the package as containing a world.  This has to happen here rather than at serialization time,
	// so that e.g. the referenced assets browser will work correctly.
	if (WorldPackage != GetTransientPackage())
	{
		WorldPackage->ThisContainsMap();
	}

	// Create new UWorld, ULevel and UModel.
	const FString WorldNameString = (WorldName != NAME_None) ? WorldName.ToString() : TEXT("Untitled");
	UWorld* NewWorld = NewObject<UWorld>(WorldPackage, *WorldNameString);
	NewWorld->SetFlags(RF_Transactional);
	NewWorld->WorldType = InWorldType;
	NewWorld->FeatureLevel = InFeatureLevel;
	NewWorld->InitializeNewWorld(UWorld::InitializationValues()
		.ShouldSimulatePhysics(false)
		.EnableTraceCollision(true)
		.CreateNavigation(true)
		.CreateAISystem(true));

	// Clear the dirty flag set during SpawnActor and UpdateLevelComponents
	WorldPackage->SetDirtyFlag(false);

	if (bAddToRoot)
	{
		// Add to root set so it doesn't get garbage collected.
		NewWorld->AddToRoot();
	}

	// Tell the engine we are adding a world (unless we are asked not to)
	if ((GEngine) && (bInformEngineOfWorld == true))
	{
		GEngine->WorldAdded(NewWorld);
	}

	return NewWorld;
}



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////				World navigation logick			  //////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



void UGameBFL::CreateNavigationData(UObject* World)
{
	auto NewWorld = Cast<UWorld>(World->GetWorld());
	if (NewWorld)
	{
		UNavigationSystemV1* NavSys = FNavigationSystem::GetCurrent<UNavigationSystemV1>(NewWorld);
		if (NavSys)
		{
			ANavigationData* DefaultData = NavSys->GetDefaultNavDataInstance(FNavigationSystem::DontCreate);
			if (DefaultData)
			{

				//const UNavigationSystemV1::ERegistrationResult Result = NavSys->RegisterNavData(nullptr);
				//NavSys->LogNavDataRegistrationResult(Result);
				return;
			}
			ANavigationData* UseNavData = NavSys->GetDefaultNavDataInstance(FNavigationSystem::Create);
			ARecastNavMesh* NavMesh = Cast<ARecastNavMesh>(UseNavData);
			//if (NavMesh)
			//{
			//	for (TFieldIterator<FProperty> PropertyIterator(NavMesh->GetClass()); PropertyIterator; ++PropertyIterator)
			//	{
			//		FProperty* Property = *PropertyIterator;
			//		FName const PropertyName = Property->GetFName();
			//		if (PropertyName == "RuntimeGeneration")
			//		{
			//			FEnumProperty* prop = Cast<FEnumProperty>(Property);
			//			if (prop)
			//			{
			//				ERuntimeGenerationType* ptrValue = prop->ContainerPtrToValuePtr<ERuntimeGenerationType>(Property);
			//				prop->GetUnderlyingProperty()->SetIntPropertyValue(ptrValue, prop->GetEnum()->GetValueByIndex(1));
			//				if (ptrValue)
			//				{
			//					

			//					//int i = (int)(*ptrValue);

			//					const TEnumAsByte<ERuntimeGenerationType> SurfaceEnum = UseNavData->GetRuntimeGenerationMode();
			//					FString EnumAsString = UEnum::GetValueAsString(SurfaceEnum.GetValue());
			//					GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("Val: %s"), *EnumAsString));

			//					//FTimerDelegate TimerCallback;
			//					//TimerCallback.BindLambda([UseNavData, i]
			//					//{


			//					//	const TEnumAsByte<ERuntimeGenerationType> SurfaceEnum = UseNavData->GetRuntimeGenerationMode();
			//					//	FString EnumAsString = UEnum::GetValueAsString(SurfaceEnum.GetValue());

			//					//	GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("Val: %s"), *EnumAsString));
			//					//});

			//					//FTimerHandle Handle;
			//					//World->GetWorld()->GetTimerManager().SetTimer(Handle, TimerCallback, 5.0f, false);
			//				}
			//			}
			//			break;

			//		}


			//	}
			//}
		}
	}
}

void UGameBFL::BuildNavigation(UObject* World)
{
	auto NewWorld = Cast<UWorld>(World->GetWorld());
	if (NewWorld)
	{
		UNavigationSystemV1* NavSys = FNavigationSystem::GetCurrent<UNavigationSystemV1>(NewWorld);
		if (NavSys)
		{
			NavSys->Build();
		}
	}
}



TArray<uint8> UGameBFL::SaveNavData(UObject* World) {
	auto NewWorld = Cast<UWorld>(World->GetWorld());
	if (NewWorld)
	{
		UNavigationSystemV1* NavSys = FNavigationSystem::GetCurrent<UNavigationSystemV1>(NewWorld);
		ANavigationData* NavData = NavSys->GetDefaultNavDataInstance(FNavigationSystem::ECreateIfEmpty::DontCreate);
		if (NavData) {
			ARecastNavMesh* NavMesh = Cast<ARecastNavMesh>(NavData);
			//NavMesh->GetGenerator()->ExportNavigationData(FString(TEXT("C:\\Users\\xxxx\\Navmesh")));
			return SaveToBinaryArray(NavData, false);
		}
	}
	TArray<uint8> t;
	return t;
}

void UGameBFL::LoadNavData(UObject* World, TArray<uint8> data) {
	auto NewWorld = Cast<UWorld>(World->GetWorld());
	if (NewWorld)
	{
		UNavigationSystemV1* NavSys = FNavigationSystem::GetCurrent<UNavigationSystemV1>(NewWorld);
		ANavigationData* NavData = NavSys->GetDefaultNavDataInstance(FNavigationSystem::ECreateIfEmpty::DontCreate);
		if (NavData) {
			ARecastNavMesh* NavMesh = Cast<ARecastNavMesh>(NavData);
			LoadFromBinaryArray(data, NavData, false);
		}
	}
}






////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////				End World logick			  //////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////






void UGameBFL::ProcessTick(TArray<UObject*> Objects, float DeltaSeconds) {
	for (auto Obj : Objects) {
		//GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Orange, FString::Printf(TEXT("Tick: %s"), *Obj->GetFName().ToString()));
		//Cast<AActor>(Obj)->TickActor(DeltaSeconds, ELevelTick::LEVELTICK_All, nullptr);
		Obj->GetWorld()->GetNavigationSystem()->Tick(DeltaSeconds);
	}
}


It looks like you are hitting some form of recursion. The first 2 worlds seem to work ok but when you delete one and spawn the next I’m suspecting you maybe missed something in the cleanup process during destroying worlds. Your camera starts jittering like it has two conflicting rotation information inputs.
Could it be that part of the deleted world is interjecting into the newly created one causing some sort of feed back look that ends in a recursion error once it hits a limit?

The problem with frame judder is I think it’s just 2 scenecapture2d trying to write to the same Rrndertatget at the same time. The real problem is at the end of the video. And it seems to be related to this code:

UPackage* NewWorldPackage = CreatePackage(nullptr);
	NewWorldPackage->SetPackageFlags(PKG_PlayInEditor);
	NewWorldPackage->PIEInstanceID = WorldPackage->GetPIEInstanceID();
	NewWorldPackage->FileName = FName(*WorldPackage->GetName());
	NewWorldPackage->SetGuid(WorldPackage->GetGuid());
	NewWorldPackage->MarkAsFullyLoaded();


	UWorld* PackageWorld = UWorld::FindWorldInPackage(WorldPackage);



	FObjectDuplicationParameters Parameters(PackageWorld, NewWorldPackage);
	//Parameters.DestName = PackageWorld->GetFName();
	Parameters.DestName = FName();
	Parameters.DestClass = PackageWorld->GetClass();
	Parameters.DuplicateMode = EDuplicateMode::PIE;
	Parameters.PortFlags = EPropertyPortFlags::PPF_Duplicate;

	NewWorld = CastChecked<UWorld>(StaticDuplicateObjectEx(Parameters));

It feels like the engine can’t duplicate the world again. But I can’t figure out what could be the reason :frowning:

Could it be

Parameters.DestName = FName();

that is causing the problem? If you run this method twice won’t the desname be the same? (Not sure if FName() just returns as empty fname?)

If you have 2 non unique overlapping destinations that might cause a problem?

Maybe this has to be
//Parameters.DestName = PackageWorld->GetFName(); as is passing in the name of the new uworld (hence unique)

Looks like deleting GEngine->TrimMemory() in UGameBFL::DestroyCreatedWorld(FUWorldContext UWorldContext)
solved the problem with crashes in standalone.

Unfortunately, the UWorld creation code only works once in a packaged game. Further takes off Fatal Error when I try to create the second. This is connected similarly with the function of duplicating the finished Uworld into a new one:

    UWorld* PackageWorld = UWorld::FindWorldInPackage(WorldPackage);
	UWorld* BlankNewWorld = UWorld::CreateWorld(EWorldType::Game, false);

	FObjectDuplicationParameters Parameters(PackageWorld, BlankNewWorld);
	//Parameters.DestName = PackageWorld->GetFName();
	static int32 i = 1;
	auto name = FString("World") + FString::FromInt(i);
	Parameters.DestName = *name;
	Parameters.DestClass = PackageWorld->GetClass();
	Parameters.DuplicateMode = EDuplicateMode::Normal;
	Parameters.PortFlags = EPropertyPortFlags::PPF_Duplicate;
	i++;
	NewWorld = CastChecked<UWorld>(StaticDuplicateObjectEx(Parameters));

Does anyone have any ideas how to make correct duplicates?

More or less working code. In a convenient way.

.h

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

#pragma once

#include "CoreMinimal.h"
#include "Subsystems/WorldSubsystem.h"
#include "UWorldSubsystem.generated.h"




USTRUCT(BlueprintType)
struct FUWorldContext
{
	GENERATED_BODY()
public:
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Test Variables")
		UWorld* ContextWorld = nullptr;


public:
	void SetWorldContext(FWorldContext* inContext) { ContextWorld = inContext->World(); }


};



/**
 * 
 */
UCLASS()
class GAMEPROJECT_API UUWorldSubsystem : public UWorldSubsystem
{
	GENERATED_BODY()
public:
	//UUWorldSubsystem();

	TMap<UWorld*, FDelegateHandle> CleanupHandles;
	TMap<UWorld*, FDelegateHandle> TickHandles;
	static TArray<UWorld*> CreatedWorlds;


	FDelegateHandle Lambda;


	FUWorldContext ActiveWorldContext;

public:

	// USubsystem implementation Begin
	virtual void Initialize(FSubsystemCollectionBase& Collection) override;
	virtual void Deinitialize() override;
	// USubsystem implementation End



public:

	UFUNCTION(BlueprintCallable, Category = "UWorldSubsystem")
		void CreateNewWorld(const TSoftObjectPtr<class UWorld> Level, const TSubclassOf<class AGameModeBase> GameMode, FUWorldContext& UWorldContext);
	UFUNCTION(BlueprintCallable, Category = "UWorldSubsystem")
		void DestroyCreatedWorld(FUWorldContext UWorldContext);
	UFUNCTION(BlueprintCallable, Category = "UWorldSubsystem")
		static void SetWorldTick(FUWorldContext UWorldContext, bool Tick);

	UFUNCTION(BlueprintCallable, Category = "UWorldSubsystem")
		TArray<FUWorldContext> GetAllCreatedWorlds();


	UFUNCTION(BlueprintCallable, Category = "UWorldSubsystem")
		APlayerController* ChangeWorld(FUWorldContext UWorldContext, APawn*& PrevPawn);


	UFUNCTION(BlueprintPure, Category = "UWorldSubsystem")
		FUWorldContext GetMainWorldContext();
	UFUNCTION(BlueprintPure, Category = "UWorldSubsystem")
		FUWorldContext GetCurrentWorldContext();

};

.cpp

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


#include "UWorldSubsystem.h"



#include "EngineUtils.h"
#include "Kismet/GameplayStatics.h"
#include "GameFramework/GameModeBase.h"


#include "UWorldCommonGameViewportClient.h"


TArray<UWorld*> UUWorldSubsystem::CreatedWorlds;

void UUWorldSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
	Super::Initialize(Collection);
	Lambda = GEngine->OnWorldDestroyed().AddLambda([&](UWorld* World) {
		if (World == GetMainWorldContext().ContextWorld) {
			//	UE_LOG(LogTemp, Warning, TEXT("MainWorld destroyed = %s"), *World->GetName());
			//	//auto CurrentWorld = ActiveWorldContext.ContextWorld;
			//	//CurrentWorld->RemoveController(CurrentWorld->GetFirstPlayerController());
			//
			
			if (CreatedWorlds.Contains(ActiveWorldContext.ContextWorld)) {
				FUWorldContext Context;
				Context.ContextWorld = ActiveWorldContext.ContextWorld;
				DestroyCreatedWorld(Context);
			}
			
			
		}
		});
}

void UUWorldSubsystem::Deinitialize()
{
	Super::Deinitialize();
	Lambda.Reset();
}

//////void UGameBFL::CreateNewWorld3(const UObject* WorldContextObject, const TSoftObjectPtr<UWorld> Level, UWorld*& World, FUWorldContext2& UWorldContext)
void UUWorldSubsystem::CreateNewWorld(const TSoftObjectPtr<UWorld> Level, TSubclassOf<class AGameModeBase> GameMode, FUWorldContext& UWorldContext)
{

	UWorld* NewWorld = nullptr;

	const FString LevelName2 = FPackageName::ObjectPathToPackageName(Level.ToString());
	//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("level name = %s"), *LevelName2));

	UPackage* WorldPackage = FindPackage(nullptr, *LevelName2);
	if (WorldPackage == nullptr)
	{
		WorldPackage = LoadPackage(nullptr, *LevelName2, ELoadFlags::LOAD_None);
		if (!WorldPackage)
		{
			GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Package not loaded")));
			return;
		}

	}

	///======

	if (!WorldPackage)
	{
		WorldPackage = CreatePackage(nullptr);
	}

	//if (InWorldType == EWorldType::PIE)
	//{
	//	WorldPackage->SetPackageFlags(PKG_PlayInEditor);
	//}

	// Mark the package as containing a world.  This has to happen here rather than at serialization time,
	// so that e.g. the referenced assets browser will work correctly.
	if (WorldPackage != GetTransientPackage())
	{
		WorldPackage->ThisContainsMap();
	}
	///======

	FName Pname = *(WorldPackage->GetFName().ToString() + FGuid::NewGuid().ToString());
	//FName Pname = MakeUniqueObjectName(WorldPackage, UPackage::StaticClass(), WorldPackage->GetFName());
	UPackage* NewWorldPackage = CreatePackage(*Pname.ToString());
	NewWorldPackage->SetPackageFlags(PKG_ContainsMap);
	//NewWorldPackage->PIEInstanceID = WorldPackage->GetPIEInstanceID();
	//NewWorldPackage->FileName = FName(*WorldPackage->GetName());
	NewWorldPackage->MarkAsFullyLoaded();

	UWorld* PackageWorld = UWorld::FindWorldInPackage(WorldPackage);











	//UWorld* NewWorld = nullptr;

	//const FString LevelName2 = FPackageName::ObjectPathToPackageName(Level.ToString());
	////GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("level name = %s"), *LevelName2));

	//UPackage* WorldPackage = FindPackage(nullptr, *LevelName2);
	//if (WorldPackage == nullptr)
	//{
	//	WorldPackage = LoadPackage(nullptr, *LevelName2, ELoadFlags::LOAD_None);
	//	if (!WorldPackage)
	//	{
	//		GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Package not loaded")));
	//		return;
	//	}

	//}


	//UWorld* PackageWorld = UWorld::FindWorldInPackage(WorldPackage);



	//UPackage* NewWorldPackage = CreatePackage(nullptr);
	////NewWorldPackage->SetPackageFlags(PKG_PlayInEditor);
	////NewWorldPackage->PIEInstanceID = PIEInstanceID;
	////NewWorldPackage->FileName = PackageFName;
	////NewWorldPackage->SetGuid(EditorLevelPackage->GetGuid());
	////NewWorldPackage->MarkAsFullyLoaded();















	FObjectDuplicationParameters Parameters(PackageWorld, NewWorldPackage);
	//FName Pname = *(WorldPackage->GetFName().ToString() + FGuid::NewGuid().ToString());
	//const FString PName = FPackageName::ObjectPathToPackageName(Level.ToString());
	//Parameters.DestName = *PName;
	Parameters.DestClass = PackageWorld->GetClass();
	Parameters.DuplicateMode = EDuplicateMode::PIE;
	Parameters.PortFlags = EPropertyPortFlags::PPF_Duplicate;


	//NewWorld = CastChecked<UWorld>(StaticDuplicateObjectEx(Parameters));
	NewWorld = Cast<UWorld>(StaticDuplicateObjectEx(Parameters));

























	NewWorld->SetShouldTick(true);

	auto GameInstance = UGameplayStatics::GetGameInstance(GEngine->GetCurrentPlayWorld());
	FWorldContext& WorldContext = GEngine->CreateNewWorldContext(EWorldType::Game);
	WorldContext.OwningGameInstance = GameInstance;
	//WorldContext.PIEInstance = -1;
	NewWorld->SetGameInstance(GameInstance);
	NewWorld->WorldType = WorldContext.WorldType;
	//NewWorld->WorldType = EWorldType::PIE;
	WorldContext.SetCurrentWorld(NewWorld);

	//NewWorld->AddController(GetMainWorld()->GetFirstPlayerController());


	auto context = GameInstance->GetWorldContext()->GameViewport;
	//ViewportClient->Init(*GameInstance->GetWorldContext(), GameInstance);
	WorldContext.GameViewport = context;


	// Add to root set so it doesn't get garbage collected.
	NewWorld->AddToRoot();

	// Clear the dirty flags set during SpawnActor and UpdateLevelComponents
	WorldPackage->SetDirtyFlag(false);
	for (UPackage* ExternalPackage : WorldPackage->GetExternalPackages())
	{
		ExternalPackage->SetDirtyFlag(false);
	}

	// Tell the engine we are adding a world (unless we are asked not to)
	if (GEngine)
	{
		GEngine->WorldAdded(NewWorld);
	}


	//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("CreateWorld: %s"), *NewWorld->GetFName().ToString()));

	//// In the PIE case the world will already have been initialized as part of CreatePIEWorldByDuplication
	if (!WorldContext.World()->bIsWorldInitialized)
	{
		WorldContext.World()->InitWorld();
	}










	FURL URL;
	//FURL URL(&WorldContext.LastURL, *NewWorld->GetFName().ToString(), ETravelType::TRAVEL_Absolute);
	//URL.AddOption(TEXT("GAME=/Game/ThirdPersonCPP/Blueprints/BpGameMode2.BpGameMode2_C"));
	URL.AddOption(TEXT("GAME=/Game/Blueprints/GameModeBP_CreatedWorld.GameModeBP_CreatedWorld_C"));
	WorldContext.World()->SetGameMode(URL);


	//WorldContext.World()->CreateAISystem();





	WorldContext.World()->InitializeActorsForPlay(URL);



	//AActor* lacder = nullptr;

	for (auto actor : NewWorld->PersistentLevel->Actors) {
		UE_LOG(LogTemp, Warning, TEXT("LoadedWorldActorsClasses: %s"), *UKismetSystemLibrary::GetDisplayName(actor));
		//if (actor->GetClass()->GetName() == "BpGameMode2_C")
		//{
		//	//lacder = actor;
		//}
	}
	UFunction* Func = NewWorld->GetAuthGameMode()->GetClass()->FindFunctionByName(FName("Load"));
	if (Func == nullptr) {
		return;
	}
	FStructOnScope FuncParam(Func);
	NewWorld->GetAuthGameMode()->ProcessEvent(Func, FuncParam.GetStructMemory());




	//UNavigationSystemV1 *NavSys = FNavigationSystem::GetCurrent<UNavigationSystemV1>(NewWorld);
	//if (NavSys)
	//{
	//	ANavigationData *UseNavData = NavSys->GetDefaultNavDataInstance(FNavigationSystem::Create);
	//	NavSys->Build();
	//}


	WorldContext.World()->BeginPlay();
	WorldContext.World()->bWorldWasLoadedThisTick = true;




	//if (!CleanupHandle.IsValid()) {

		 //Tick call in PIE
	auto TickHandle = FWorldDelegates::OnWorldTickStart.AddLambda([NewWorld, this](UWorld* World, ELevelTick TickType, float DeltaSeconds) {
		if (World == GEngine->GetCurrentPlayWorld() && GEngine->GetCurrentPlayWorld()->WorldType == EWorldType::PIE) {
			auto TickHand = this->TickHandles.Find(NewWorld);
			if (TickHand->IsValid()) {
				if (NewWorld->ShouldTick())
				{
					NewWorld->Tick(TickType, DeltaSeconds);
					//GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Yellow, FString::Printf(TEXT("TickInWorld: %s"), *NewWorld->GetFName().ToString()));
					//UE_LOG(LogTemp, Warning, TEXT("TickInWorld: %s"), *NewWorld->GetFName().ToString());
				}

			}
		}});
	if (TickHandle.IsValid())
	{
		GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Yellow, FString::Printf(TEXT("TickHackSet")));
		UE_LOG(LogTemp, Warning, TEXT("TickHackSet"));
	}
	TickHandles.Add(NewWorld, TickHandle);


	//auto CHandle = FWorldDelegates::OnPostWorldCleanup.AddLambda([NewWorld](UWorld* World, bool bSessionEnded, bool bCleanupResources) {
	//	if (!CreatedWorlds.Contains(World)) {
	//		;
	//		auto CLHandle = CleanupHandles.Find(NewWorld);
	//		if (CLHandle) {
	//			FWorldDelegates::OnPostWorldCleanup.Remove(*CLHandle);
	//			CLHandle->Reset();
	//			CleanupHandles.Remove(NewWorld);
	//		}
	//		auto TickHand = TickHandles.Find(NewWorld);
	//		if (TickHand && TickHand->IsValid()) {
	//			FWorldDelegates::OnWorldTickStart.Remove(*TickHand);
	//			TickHand->Reset();
	//			TickHandles.Remove(NewWorld);
	//		}


	//		if (NewWorld) {
	//			auto Name = NewWorld->GetMapName();
	//			for (FActorIterator ActorIt(NewWorld); ActorIt; ++ActorIt)
	//			{
	//				//ActorIt->RouteEndPlay(EEndPlayReason::LevelTransition);
	//				ActorIt->Destroy();
	//			}

	//			// Do this after destroying pawns/playercontrollers, in case that spawns new things (e.g. dropped weapons)
	//			//WorldRef->CleanupWorld();

	//			//GEngine->WorldDestroyed(WorldRef);

	//			CreatedWorlds.Remove(NewWorld);

	//			GEngine->DestroyWorldContext(NewWorld);
	//			NewWorld->DestroyWorld(true);

	//			//GEngine->TrimMemory();
	//			//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Created World destroyed: %s"), *WorldRef->GetFName().ToString()));
	//			UE_LOG(LogTemp, Warning, TEXT("Created World destroyed: %s"), *Name);

	//		}


	//		//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("DestroyedWorld: %s"), *World->GetFName().ToString()));
	//		UE_LOG(LogTemp, Warning, TEXT("DestroyedWorld: %s"), *World->GetFName().ToString());
	//	}
	//	});
	//CleanupHandles.Add(NewWorld, CHandle);
	//}


	CreatedWorlds.Add(NewWorld);

	UWorldContext.SetWorldContext(&WorldContext);
	//World = NewWorld;
	//
	//
	//auto vp = World->GetGameViewport();
	//if (vp) {
	//	GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Exist viewport")));
	//	//World->GetGameViewport()->Init(WorldContext, GameInstance);
	//	GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Player: %d"), World->GetAuthGameMode()->GetNumPlayers()));
	//
	//}
	//else
	//{
	//	GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("No viewport")));
	//}

	//GEngine->GameViewport->Viewport->;
	//FViewportClient* Client = GEngine->GameViewport->Viewport->GetClient();
	//Client->
	//FViewport::SetViewportClient;

}


void UUWorldSubsystem::DestroyCreatedWorld(FUWorldContext UWorldContext) {

	//auto WorldRef = Cast<UWorld>(World->GetWorld());
	auto WorldRef = UWorldContext.ContextWorld;

	//WorldRef->SetShouldTick(false);

	if (CreatedWorlds.Contains(WorldRef)) {
		/*auto CleanDelegat = CleanupHandles.Find(WorldRef);
		if (CleanDelegat->IsValid()) {
			FWorldDelegates::OnPostWorldCleanup.Remove(*CleanDelegat);
			CleanDelegat->Reset();
		}*/
		auto TickHand = TickHandles.Find(WorldRef);
		if (TickHand && TickHand->IsValid()) {
			FWorldDelegates::OnWorldTickStart.Remove(*TickHand);
			TickHand->Reset();
			TickHandles.Remove(WorldRef);
		}
		CreatedWorlds.Remove(WorldRef);
	}

	//if (WorldRef) {
	//	auto WorldName = WorldRef->GetMapName();
	//	WorldRef->DestroyWorld(true);

	//	WorldRef->MarkAsGarbage();
	//	UE_LOG(LogTemp, Warning, TEXT("Destroy UWorld from player event: %s"), *WorldName);
	//	}

	if (WorldRef)
	{
		auto WorldName = WorldRef->GetMapName();
		for (FActorIterator ActorIt(WorldRef); ActorIt; ++ActorIt)
		{

			//ActorIt->RouteEndPlay(EEndPlayReason::LevelTransition);
			ActorIt->Destroy();
		}

		// Do this after destroying pawns/playercontrollers, in case that spawns new things (e.g. dropped weapons)
		//WorldRef->CleanupWorld();

		//WorldRef->MarkAsGarbage();


		WorldRef->DestroyWorld(true);
		GEngine->DestroyWorldContext(WorldRef);
		GEngine->WorldDestroyed(WorldRef);


		//GEngine->TrimMemory();
		//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Created World destroyed: %s"), *WorldRef->GetFName().ToString()));
		UE_LOG(LogTemp, Warning, TEXT("Destroy UWorld from player event: %s"), *WorldName);
	}

}


void UUWorldSubsystem::SetWorldTick(FUWorldContext UWorldContext, bool Tick) {
	auto contest = UWorldContext.ContextWorld;
		if(IsValid(contest)) contest->SetShouldTick(Tick);
}



TArray<FUWorldContext> UUWorldSubsystem::GetAllCreatedWorlds()
{
	TArray<FUWorldContext> ContextArray;
	for(auto world : CreatedWorlds) {
		FUWorldContext ct;
		ct.ContextWorld = world;
		ContextArray.Add(ct);
	}
	return ContextArray;
}

APlayerController* UUWorldSubsystem::ChangeWorld(FUWorldContext UWorldContext, APawn*& PrevPawn) {

	auto MainWorld = GetMainWorldContext().ContextWorld;
	auto NewWorld = UWorldContext.ContextWorld;
	if (!IsValid(NewWorld)) return nullptr;
	auto WorldContext = GEngine->GetWorldContextFromWorld(NewWorld);

	auto GameInstance = UGameplayStatics::GetGameInstance(GEngine->GetCurrentPlayWorld());
	//auto context = GameInstance->GetWorldContext()->GameViewport;

	//switch render to new UWorld
	//NewWorld->GetGameViewport()->Init(*WorldContext, GameInstance);
	Cast<UUWorldCommonGameViewportClient>(NewWorld->GetGameViewport())->ChangeRenderWorld(NewWorld);

	//find PC in worlds
	APlayerController* PC = nullptr;

	//if (MainWorld != NewWorld && !IsValid(NewWorld->GetFirstPlayerController())) {
		NewWorld->AddController(GEngine->GetCurrentPlayWorld()->GetFirstPlayerController());
	//}

	//if (MainWorld == NewWorld) {
	//	auto ctr = NewWorld->GetFirstPlayerController();
	//	NewWorld->RemoveController(ctr);
	//}
	ActiveWorldContext = UWorldContext;
	//auto World = GetMainWorld();
	//if (IsValid(World)) {

	//	PC = World->GetFirstPlayerController();

	//	if (!PC) {
	//		for (auto CurWorld : CreatedWorlds)
	//		{
	//			PC = CurWorld->GetFirstPlayerController();
	//			if (PC) break;
	//		}
	//	}


	//	if (PC) PrevPawn = PC->GetPawn();
	//}

	return PC ? PC : nullptr;
}

FUWorldContext UUWorldSubsystem::GetMainWorldContext()
{
	FUWorldContext UWorldContext;
	UWorldContext.ContextWorld = GEngine->GetCurrentPlayWorld();
	return UWorldContext;
}


FUWorldContext UUWorldSubsystem::GetCurrentWorldContext()
{
	return ActiveWorldContext;
}

Problem: Before calling any OpenLevel, you need to call the DestroyCreatedWorld() function on ALL created worlds. Otherwise, there will be problems with the creation of worlds at new levels or transitions to them.

Issue 2: After UWorld is created and then OpenLevel is called. Going to UWorld is no longer possible.

If someone could help fix this I would be grateful as there are no more ideas about this.

P.S. Many problems can arise in a packed game, keep in mind.

GitHub: GitHub - Drikon/WorldsCreation