Exemplo n.º 1
0
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);
}