Not (I wish), but I tried the same thing as you. In my experience you have two options.
- Copy the code from the VictoryPlugin, for the spawn node, in your own C++ function library and modify it:
AC_Building* UC_FunctionLibrary::SpawnBuildingIntoLevel(UObject* WorldContextObject, TSubclassOf<AC_Building> BuildingType, ESpawnActorCollisionHandlingMethod CollisionOverride, FTransform const SpawnTransform, int32 CityIndex, EBuildingTier BuildingTier, bool IsAlive, bool PhysicsEnabled, bool IsTwin, AActor* Owner)
{
if (!GEngine)
{
UE_LOG(LogCore, Error, TEXT("FAILED: %s - SpawnBuildingIntoLevel -> GEngine is not valid!"), *WorldContextObject->GetName());
return nullptr;
}
if (!BuildingType)
{
UE_LOG(LogCore, Error, TEXT("FAILED: %s - SpawnBuildingIntoLevel -> BuildingType is not valid!"), *WorldContextObject->GetName());
return nullptr;
}
//using a context to get the world!
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
if (!World)
{
UE_LOG(LogCore, Error, TEXT("FAILED: %s - SpawnBuildingIntoLevel -> World is not valid!"), *WorldContextObject->GetName());
return nullptr;
}
//Create SpawnParameters
FActorSpawnParameters SpawnParameters;
SpawnParameters.SpawnCollisionHandlingOverride = CollisionOverride;
SpawnParameters.bDeferConstruction = true;
SpawnParameters.bAllowDuringConstructionScript = false;
SpawnParameters.Owner = Owner;
//Get Level from Name based on CityIndex.
ULevel* FoundLevel = nullptr;
FString LevelName = GetGameSettings()->CityPrefix;
LevelName += DoubleDigitInt(CityIndex);
for (const ULevelStreaming* EachLevel : World->StreamingLevels)
{
if (!EachLevel) continue;
//~~~~~~~~~~~~~~~~
ULevel* LevelPtr = EachLevel->GetLoadedLevel();
//Valid?
if (!LevelPtr) continue;
FString x = EachLevel->GetWorldAssetPackageName();
//
x = x.Right(7);
if (x == LevelName)
{
FoundLevel = LevelPtr;
break;
}
}
//~~~~~~~~~~~~~~~~~~~~~
if (FoundLevel)
{
SpawnParameters.OverrideLevel = FoundLevel;
}
//~~~~~~~~~~~~~~~~~~~~~
AC_Building* SpawnedBuilding = nullptr;
//World->SpawnActorDeferred<BuildingType>(BuildingType, &, &, nullptr, nullptr, false);
//World->SpawnActor(SpawnParameters);
SpawnedBuilding = World->SpawnActor<AC_Building>(BuildingType, SpawnTransform.GetLocation(), SpawnTransform.Rotator(), SpawnParameters);
//SpawnedBuilding = World->SpawnActorDeferred<AC_Building>(BuildingType, SpawnTransform);
if (SpawnedBuilding)
{
SpawnedBuilding->SetCityIndex(CityIndex);
SpawnedBuilding->BuildingTier = BuildingTier;
SpawnedBuilding->isAlive = IsAlive;
SpawnedBuilding->isBuildingTwin = IsTwin;
SpawnedBuilding->PhysicsEnabled = PhysicsEnabled;
UGameplayStatics::FinishSpawningActor(SpawnedBuilding, SpawnTransform);
}
else
{
UE_LOG(LogCore, Error, TEXT("FAILED: %s - SpawnBuildingIntoLevel -> SpawnedBuilding failed to spawn!"), *WorldContextObject->GetName());
return nullptr;
}
return SpawnedBuilding;
}
- Use the default spawning node and assign an actor that already is in that sublevel as the “Owner”. will set the spawn actor as part of that sublevel as well. <- I did by accident and seemed to work.