If I create a new World Settings derived class, change my Project Settings to use this as the default World Settings, then save a map with custom settings from this new class, how do I later remove this custom World Settings association if I decide to no longer want to use it with the map?
Changing the default World Settings for the project ensures that other new maps don’t use it, but it seems once you’ve saved a map with a custom World Settings class it always retains that association with it. That is causing an engine crash if you later remove the custom World Settings class completely from the project since now it doesn’t exist when that map tries to load.
No, I never did. It was something I discovered while prototyping for a feature and created a custom World Settings class as part of it. I later removed that custom World Settings class from the project as we did not need it for the feature, but I noticed this effect on the test map that was saved using it.
Since it was all happening on a “throw away” test map, it didn’t matter too much for us, but this could be a problem for others that have a map with real work done on it.
I solved that creating a blueprintable function that receive a map, load that map and search for any WorldSettings Actor that is not a instance of the current WorldSettingsClass defined in GEngine:
void USREFunctionLibrary::RemoveDuplicatedWorldSettingsFromMap(const TSoftObjectPtr<UWorld> Map)
{
UWorld* World = Map.LoadSynchronous();
TArray<AActor*> WorldSettingsList;
UGameplayStatics::GetAllActorsOfClass(World, AWorldSettings::StaticClass(), WorldSettingsList);
for (AActor* Actor : WorldSettingsList)
{
if (!Actor->IsA(GEngine->WorldSettingsClass))
{
Actor->Destroy();
UE_LOG(LogBlueprintUserMessages, Warning, TEXT("Removing Actor: %s"), *Actor->GetName());
}
}
UPackage* Outermost = World->GetPackage();
Outermost->MarkPackageDirty();
FSavePackageResultStruct Result = UPackage::Save(Outermost, nullptr, RF_Standalone, *Map.ToString(), GError,
nullptr, true, true, SAVE_NoError);
if (Result.Result == ESavePackageResult::Success)
{
UE_LOG(LogBlueprintUserMessages, Warning, TEXT("Successefully saved map!"));
}
else
{
UE_LOG(LogBlueprintUserMessages, Warning, TEXT("Error: could not save map!"));
}
}