Loading World Instance sets all content's position incorrectly

I’m trying to create and load a unique instance of a world. This “works”, with the exception that all of the world’s contents are re-positioned to the center of that world’s bounds. I would expect the world would load with it’s contents in the same position I saved them in, just offset by the given LevelTransform.

Additionally, the world doesn’t appear in the Windows>Level list.

Code:

ULevelStreaming* UWorldLevelLoader::AddLevelInstance(FString UniqueInstanceName, FString PackageNameToLoad, const FTransform& LevelTransform)
{
	ULevelStreaming* StreamingLevelInstance = nullptr;

	UWorld* InWorld = URoadPrototypeGameInstance::World;
	if (InWorld)
	{
		// check if instance name is unique among existing streaming level objects
		const bool bUniqueName = (InWorld->StreamingLevels.IndexOfByPredicate(ULevelStreaming::FPackageNameMatcher(FName(*UniqueInstanceName))) == INDEX_NONE);

		if (bUniqueName)
		{
			StreamingLevelInstance = Cast<ULevelStreamingKismet>(StaticConstructObject(ULevelStreamingKismet::StaticClass(), URoadPrototypeGameInstance::World, NAME_None, RF_NoFlags, NULL));
			// new level streaming instance will load the same map package as this object
			StreamingLevelInstance->PackageNameToLoad = FName(*PackageNameToLoad);
			// under a provided unique name
			StreamingLevelInstance->SetWorldAssetByPackageName(FName(*UniqueInstanceName));
			StreamingLevelInstance->bShouldBeLoaded = true;
			StreamingLevelInstance->bShouldBeVisible = true;
			StreamingLevelInstance->LevelTransform = LevelTransform;

			// add a new instance to streaming level list
			InWorld->StreamingLevels.Add(StreamingLevelInstance);
		}
		else
		{
			UE_LOG(LogStreaming, Warning, TEXT("Provided streaming level instance name is not unique: %s"), *UniqueInstanceName);
		}
	}

	return StreamingLevelInstance;
}

Hi,

When editor saves sub-level it removes LevelTransform from it in UEditorEngine::OnPreSaveWorld. So basically content is saved to the disk without LevelTransform applied. You can see at what location all actors are if you open a sub-level map file as a standalone level in the editor.

Standalone and in editor have the same result, all of the world’s objects are in the wrong location.

If I comment out the following everything spawns in the correct location. But I want to be able to spawn and move the world to different locations.

StreamingLevelInstance->LevelTransform = LevelTransform;

Update: Stepping through the code when a transform is provided. In USceneComponent::SetRelativeLocationAndRotation the DesiredDelta is that actor’s delta to the target level transform instead of moving relative to it’s original world transform. I’m still not sure how to resolve this but it’s more information.

Update #2: I found a work around that might explain what you said ddvlost. If I put a cube at 0,0,0 in the loaded world and parented all of the world objects to it they get streaming in at the correct position. So it seems objects relative to the world don’t work, but objects relative to their parents do.

Well, let’s say your world has one actor at (0,0,100) location. When you load it with LevelTransform translation part set to (0,0,200) you should see you actor at (0,0,300) location. If it’s not it’s bug then. I would recommend to add your world as a sub-level to the empty map in the editor and using “Level details” try applying different transforms to it to see if it works as you expect.

Using your example, after applying the transform the actor was (0,0,200). I was seeing all of the actors positions replaced with the LevelTransform. Perhaps this is caused due to using CreateInstance? I’ll try the functionality in editor as you recommended and see if it acts differently.

If it’s just replacing all actors transforms with a LevelTransform then all your actors will be at one location in the world.