void FLevelCollectionModel::UnloadLevels(const FLevelModelList& InLevelList) { if (InLevelList.Num() == 0) { return; } // If matinee is opened, and if it belongs to the level being removed, close it if (GLevelEditorModeTools().IsModeActive(FBuiltinEditorModes::EM_InterpEdit)) { TArray<ULevel*> LevelsToRemove = GetLevelObjectList(InLevelList); const FEdModeInterpEdit* InterpEditMode = (const FEdModeInterpEdit*)GLevelEditorModeTools().GetActiveMode(FBuiltinEditorModes::EM_InterpEdit); if (InterpEditMode && InterpEditMode->MatineeActor && LevelsToRemove.Contains(InterpEditMode->MatineeActor->GetLevel())) { GLevelEditorModeTools().ActivateDefaultMode(); } } else if(GLevelEditorModeTools().IsModeActive(FBuiltinEditorModes::EM_Landscape)) { GLevelEditorModeTools().ActivateDefaultMode(); } // Remove each level! // Take a copy of the list rather than using a reference to the selected levels list, as this will be modified in the loop below const FLevelModelList LevelListCopy = InLevelList; for (auto It = LevelListCopy.CreateConstIterator(); It; ++It) { TSharedPtr<FLevelModel> LevelModel = (*It); ULevel* Level = LevelModel->GetLevelObject(); if (Level != NULL && !LevelModel->IsPersistent()) { // Unselect all actors before removing the level // This avoids crashing in areas that rely on getting a selected actors level. The level will be invalid after its removed. for (auto ActorIt = Level->Actors.CreateIterator(); ActorIt; ++ActorIt) { Editor->SelectActor((*ActorIt), /*bInSelected=*/ false, /*bSelectEvenIfHidden=*/ false); } { FUnmodifiableObject ImmuneWorld(CurrentWorld.Get()); EditorLevelUtils::RemoveLevelFromWorld(Level); } } } Editor->ResetTransaction( LOCTEXT("RemoveLevelTransReset", "Removing Levels from World") ); // Collect garbage to clear out the destroyed level CollectGarbage( GARBAGE_COLLECTION_KEEPFLAGS ); PopulateLevelsList(); }
FSlateTextureDataPtr FTileThumbnail::UpdateThumbnail() { // No need images for persistent and always loaded levels if (TileModel.IsPersistent()) { return ToSlateTextureData(nullptr); } // Load image from a package header if (!TileModel.IsVisible() || TileModel.IsSimulating()) { const FName LevelAssetName = TileModel.GetAssetName(); TSet<FName> ObjectFullNames; ObjectFullNames.Add(LevelAssetName); FThumbnailMap ThumbnailMap; if (ThumbnailTools::ConditionallyLoadThumbnailsFromPackage(TileModel.GetPackageFileName(), ObjectFullNames, ThumbnailMap)) { const FObjectThumbnail* ObjectThumbnail = ThumbnailMap.Find(LevelAssetName); return ToSlateTextureData(ObjectThumbnail); } } // Render image from a visible level else { ULevel* TargetLevel = TileModel.GetLevelObject(); if (TargetLevel) { FIntPoint RTSize = ThumbnailRenderTarget->GetSizeXY(); // Set persistent world package as transient to avoid package dirtying during thumbnail rendering FUnmodifiableObject ImmuneWorld(TargetLevel->OwningWorld); FObjectThumbnail NewThumbnail; // Generate the thumbnail ThumbnailTools::RenderThumbnail( TargetLevel, RTSize.X, RTSize.Y, ThumbnailTools::EThumbnailTextureFlushMode::NeverFlush, ThumbnailRenderTarget, &NewThumbnail ); UPackage* MyOutermostPackage = CastChecked<UPackage>(TargetLevel->GetOutermost()); ThumbnailTools::CacheThumbnail(TileModel.GetAssetName().ToString(), &NewThumbnail, MyOutermostPackage); return ToSlateTextureData(&NewThumbnail); } } return ToSlateTextureData(nullptr); }