FFoliageInstanceBaseId FFoliageInstanceBaseCache::AddInstanceBaseId(UActorComponent* InComponent) { FFoliageInstanceBaseId BaseId = FFoliageInstanceBaseCache::InvalidBaseId; if (InComponent && !InComponent->IsCreatedByConstructionScript()) { BaseId = GetInstanceBaseId(InComponent); if (BaseId == FFoliageInstanceBaseCache::InvalidBaseId) { BaseId = NextBaseId++; FFoliageInstanceBaseInfo BaseInfo(InComponent); InstanceBaseMap.Add(BaseId, BaseInfo); InstanceBaseInvMap.Add(BaseInfo.BasePtr, BaseId); check(InstanceBaseMap.Num() == InstanceBaseInvMap.Num()); ULevel* ComponentLevel = InComponent->GetComponentLevel(); if (ComponentLevel) { UWorld* ComponentWorld = Cast<UWorld>(ComponentLevel->GetOuter()); if (ComponentWorld) { auto WorldKey = TAssetPtr<UWorld>(ComponentWorld); InstanceBaseLevelMap.FindOrAdd(WorldKey).Add(BaseInfo.BasePtr); } } } } return BaseId; }
/** * Assembles the set of all referenced worlds. * * @param OutWorlds [out] The set of referenced worlds. * @param bIncludeGWorld If true, include GWorld in the output list. * @param bOnlyEditorVisible If true, only sub-levels that should be visible in-editor are included */ void GetWorlds(UWorld* InWorld, TArray<UWorld*>& OutWorlds, bool bIncludeInWorld, bool bOnlyEditorVisible) { OutWorlds.Empty(); if ( bIncludeInWorld ) { OutWorlds.AddUnique( InWorld ); } // Iterate over the world's level array to find referenced levels ("worlds"). We don't for ( int32 LevelIndex = 0 ; LevelIndex < InWorld->StreamingLevels.Num() ; ++LevelIndex ) { ULevelStreaming* StreamingLevel = InWorld->StreamingLevels[LevelIndex]; if ( StreamingLevel ) { // If we asked for only sub-levels that are editor-visible, then limit our results appropriately bool bShouldAlwaysBeLoaded = false; // Cast< ULevelStreamingAlwaysLoaded >( StreamingLevel ) != NULL; if( !bOnlyEditorVisible || bShouldAlwaysBeLoaded || StreamingLevel->bShouldBeVisibleInEditor ) { const ULevel* Level = StreamingLevel->GetLoadedLevel(); // This should always be the case for valid level names as the Editor preloads all packages. if ( Level != NULL ) { // Newer levels have their packages' world as the outer. UWorld* World = Cast<UWorld>( Level->GetOuter() ); if ( World != NULL ) { OutWorlds.AddUnique( World ); } } } } } // Levels can be loaded directly without StreamingLevel facilities for ( int32 LevelIndex = 0 ; LevelIndex < InWorld->GetLevels().Num() ; ++LevelIndex ) { ULevel* Level = InWorld->GetLevel(LevelIndex); if ( Level ) { // Newer levels have their packages' world as the outer. UWorld* World = Cast<UWorld>( Level->GetOuter() ); if ( World != NULL ) { OutWorlds.AddUnique( World ); } } } }
void FWorldTileModel::OnStreamingLevelsPropertyChanged() { ULevel* Level = GetLevelObject(); if (Level == NULL) { TileDetails->StreamingLevels.Empty(); return; } // Delete all streaming levels from the world objects CastChecked<UWorld>(Level->GetOuter())->StreamingLevels.Empty(); // Recreate streaming levels using settings stored in the tile details for (auto It = TileDetails->StreamingLevels.CreateIterator(); It; ++It) { FTileStreamingLevelDetails& StreamingLevelDetails = (*It); FName PackageName = StreamingLevelDetails.PackageName; if (PackageName != NAME_None && FPackageName::DoesPackageExist(PackageName.ToString())) { UClass* StreamingClass = FTileStreamingLevelDetails::StreamingMode2Class(StreamingLevelDetails.StreamingMode); AddStreamingLevel(StreamingClass, PackageName); } } }
ULevel* AddLevelToWorld( UWorld* InWorld, const TCHAR* LevelPackageName, UClass* LevelStreamingClass) { ULevel* NewLevel = NULL; bool bIsPersistentLevel = (InWorld->PersistentLevel->GetOutermost()->GetName() == FString(LevelPackageName)); if ( bIsPersistentLevel || FLevelUtils::FindStreamingLevel( InWorld, LevelPackageName ) ) { // Do nothing if the level already exists in the world. FMessageDialog::Open( EAppMsgType::Ok, NSLOCTEXT("UnrealEd", "LevelAlreadyExistsInWorld", "A level with that name already exists in the world.") ); } else { // If the selected class is still NULL, abort the operation. if ( LevelStreamingClass == NULL ) { return NULL; } const FScopedBusyCursor BusyCursor; ULevelStreaming* StreamingLevel = static_cast<ULevelStreaming*>( StaticConstructObject( LevelStreamingClass, InWorld, NAME_None, RF_NoFlags, NULL) ); // Associate a package name. StreamingLevel->PackageName = LevelPackageName; // Seed the level's draw color. StreamingLevel->DrawColor = FColor::MakeRandomColor(); // Add the new level to world. InWorld->StreamingLevels.Add( StreamingLevel ); // Refresh just the newly created level. TArray<ULevelStreaming*> LevelsForRefresh; LevelsForRefresh.Add( StreamingLevel ); InWorld->RefreshStreamingLevels( LevelsForRefresh ); InWorld->MarkPackageDirty(); NewLevel = StreamingLevel->GetLoadedLevel(); if ( NewLevel != NULL ) { EditorLevelUtils::SetLevelVisibility( NewLevel, true, true ); } // Levels migrated from other projects may fail to load their world settings // If so we create a new AWorldSettings actor here. if ( NewLevel->Actors[0] == NULL ) { UWorld *SubLevelWorld = CastChecked<UWorld>(NewLevel->GetOuter()); if (SubLevelWorld != NULL) { FActorSpawnParameters SpawnInfo; SpawnInfo.bNoCollisionFail = true; SpawnInfo.Name = GEngine->WorldSettingsClass->GetFName(); AWorldSettings* NewWorldSettings = SubLevelWorld->SpawnActor<AWorldSettings>( GEngine->WorldSettingsClass, SpawnInfo ); NewLevel->Actors[0] = NewWorldSettings; } else { FMessageDialog::Open( EAppMsgType::Ok, NSLOCTEXT("UnrealEd", "LevelHasNoWorldSettings", "AddLevelToWorld: The level has no World Settings.") ); } } } return NewLevel; }