UK2Node_PlayMovieScene* FSequencerActorBindingManager::CreateNewPlayMovieSceneNode( UMovieScene* MovieScene ) const
{
	// Grab the world object for this editor
	check( MovieScene != NULL );
	
	ULevel* Level = ActorWorld->GetCurrentLevel();
	check( Level != NULL );
	
	// Here, we'll create a level script if one does not yet exist.
	const bool bDontCreate = false;
	ULevelScriptBlueprint* LSB = Level->GetLevelScriptBlueprint( bDontCreate );
	if( LSB != NULL )
	{
		UEdGraph* TargetGraph = NULL;
		if( LSB->UbergraphPages.Num() > 0 )
		{
			TargetGraph = LSB->UbergraphPages[0]; // Just use the first graph
		}
		
		if( ensure( TargetGraph != NULL ) )
		{
			// Figure out a decent place to stick the node
			const FVector2D NewNodePos = TargetGraph->GetGoodPlaceForNewNode();
			
			// Create a new node
			UK2Node_PlayMovieScene* TemplateNode = NewObject<UK2Node_PlayMovieScene>();
			TemplateNode->SetMovieScene( MovieScene );
			return FEdGraphSchemaAction_K2NewNode::SpawnNodeFromTemplate<UK2Node_PlayMovieScene>(TargetGraph, TemplateNode, NewNodePos);;
		}
	}
	
	return NULL;
}
Пример #2
0
void UUnrealEdEngine::MakeSelectedActorsLevelCurrent()
{
	ULevel* LevelToMakeCurrent = NULL;

	// Look to the selected actors for the level to make current.
	// If actors from multiple levels are selected, do nothing.
	for ( FSelectionIterator It( GetSelectedActorIterator() ) ; It ; ++It )
	{
		AActor* Actor = static_cast<AActor*>( *It );
		checkSlow( Actor->IsA(AActor::StaticClass()) );

		ULevel* ActorLevel = Actor->GetLevel();

		if ( !LevelToMakeCurrent )
		{
			// First assignment.
			LevelToMakeCurrent = ActorLevel;
		}
		else if ( LevelToMakeCurrent != ActorLevel )
		{
			// Actors from multiple levels are selected -- abort.
			LevelToMakeCurrent = NULL;
			break;
		}
	}

	// Change the current level to something different
	if ( LevelToMakeCurrent && !LevelToMakeCurrent->IsCurrentLevel() )
	{
		EditorLevelUtils::MakeLevelCurrent( LevelToMakeCurrent );
	}
}
Пример #3
0
bool ALevelScriptActor::RemoteEvent(FName EventName)
{
	bool bFoundEvent = false;

	// Iterate over all levels, and try to find a matching function on the level's script actor
	for( TArray<ULevel*>::TConstIterator it = GetWorld()->GetLevels().CreateConstIterator(); it; ++it )
	{
		ULevel* CurLevel = *it;
		if( CurLevel )
		{
			ALevelScriptActor* LSA = CurLevel->GetLevelScriptActor();
			if( LSA )
			{
				// Find an event with no parameters
				UFunction* EventTarget = LSA->FindFunction(EventName);
				if( EventTarget && EventTarget->NumParms == 0)
				{
					LSA->ProcessEvent(EventTarget, NULL);
					bFoundEvent = true;
				}
			}
		}
	}

	return bFoundEvent;
}
Пример #4
0
void FEdModeLevel::SetLevel( ULevelStreaming* LevelStream )
{
	if( SelectedLevel != NULL && SelectedLevel != LevelStream )
	{
		// Changed level need to apply PostEditMove to the actors we moved in the last level
		ApplyPostEditMove();
	}

	SelectedLevel = LevelStream;
	bIsDirty = false;
	if( SelectedLevel )
	{
		LevelTransform = SelectedLevel->LevelTransform;		
		ULevel* Level = SelectedLevel->GetLoadedLevel();


		// Calculate the Level bounds box
		LevelBounds = FBox(0);

		if( Level )
		{
			for( int32 ActorIndex=0; ActorIndex< Level->Actors.Num(); ActorIndex++ )
			{
				AActor* Actor = Level->Actors[ActorIndex];

				// Don't include the builder brush or the world settings as they can artificially make the level bounds bigger
				if( Actor && FActorEditorUtils::IsABuilderBrush(Actor) == false && Level->GetWorldSettings() != Actor )
				{
					LevelBounds += Actor->GetComponentsBoundingBox();
				}
			}
		}		
	}	
	GEditor->RedrawAllViewports();
}
Пример #5
0
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;
}
Пример #6
0
void FLevelModel::SetVisible(bool bVisible)
{
	//don't create unnecessary transactions
	if (IsVisible() == bVisible)
	{
		return;
	}

	const bool oldIsDirty = IsDirty();

	const FScopedTransaction Transaction(LOCTEXT("ToggleVisibility", "Toggle Level Visibility"));

	//this call hides all owned actors, etc
	EditorLevelUtils::SetLevelVisibility( GetLevelObject(), bVisible, false );

	if (!oldIsDirty)
	{
		// don't set the dirty flag if we're just changing the visibility of the level within the editor
		ULevel* Level = GetLevelObject();
		if (Level)
		{
			Level->GetOutermost()->SetDirtyFlag(false);
		}
	}
}
		/** Generates a sub-level Blueprints sub-menu */
		static void MakeSubLevelsMenu(FMenuBuilder& InMenuBuilder, TWeakPtr< SLevelEditor > InLvlEditor)
		{
			FSlateIcon EditBP(FEditorStyle::Get().GetStyleSetName(), TEXT("LevelEditor.OpenLevelBlueprint"));

			InMenuBuilder.BeginSection(NAME_None, LOCTEXT("SubLevelsHeading", "Sub-Level Blueprints"));
			{
				UWorld* World = InLvlEditor.Pin()->GetWorld();
				for (int32 iLevel = 0; iLevel < World->GetNumLevels(); iLevel++)
				{
					ULevel* Level = World->GetLevel(iLevel);
					if (Level != NULL && Level->GetOutermost() != NULL)
					{
						if (!Level->IsPersistentLevel())
						{
							FUIAction UIAction
								(
								FExecuteAction::CreateStatic(&FLevelEditorToolBar::OnOpenSubLevelBlueprint, Level)
								);

							FText DisplayName = FText::Format(LOCTEXT("SubLevelBlueprintItem", "Edit {LevelName}"), FText::FromString(FPaths::GetCleanFilename(Level->GetOutermost()->GetName())));
							InMenuBuilder.AddMenuEntry(DisplayName, FText::GetEmpty(), EditBP, UIAction);
						}
					}
				}
			}
			InMenuBuilder.EndSection();
		}
Пример #8
0
ULevelStreaming* FWorldTileModel::CreateAssosiatedStreamingLevel()
{
	ULevelStreaming* AssociatedStreamingLevel = NULL;
	ULevel* Level = GetLevelObject();
		
	if (Level)
	{
		FName PackageName = Level->GetOutermost()->GetFName();
		UWorld* PersistentWorld = LevelCollectionModel.GetWorld();
				
		// Try to find existing object first
		int32 FoundIndex = PersistentWorld->StreamingLevels.FindMatch(ULevelStreaming::FPackageNameMatcher(PackageName));
		if (FoundIndex != INDEX_NONE)
		{
			AssociatedStreamingLevel = PersistentWorld->StreamingLevels[FoundIndex];
		}
		else
		{
			// Create new streaming level
			AssociatedStreamingLevel = Cast<ULevelStreaming>(
				StaticConstructObject(ULevelStreamingKismet::StaticClass(), PersistentWorld, NAME_None, RF_Transient, NULL)
				);

			//
			AssociatedStreamingLevel->PackageName		= PackageName;
			AssociatedStreamingLevel->DrawColor			= FColor::MakeRandomColor();
			AssociatedStreamingLevel->LevelTransform	= FTransform::Identity;
			AssociatedStreamingLevel->PackageNameToLoad	= PackageName;
			//
			PersistentWorld->StreamingLevels.Add(AssociatedStreamingLevel);
		}
	}

	return AssociatedStreamingLevel;
}
Пример #9
0
void ALevelBounds::BroadcastLevelBoundsUpdated()
{
	ULevel* Level = GetLevel();
	if (Level && 
		Level->LevelBoundsActor.Get() == this)
	{
		Level->BroadcastLevelBoundsActorUpdated();
	}
}
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);
}
EVisibility SWorldHierarchyItem::GetColorButtonVisibility() const
{
	EVisibility Result = EVisibility::Hidden;
	if (LevelModel.IsValid())
	{
		ULevel* LevelObject = LevelModel->GetLevelObject();
		if (LevelObject && !LevelObject->IsPersistentLevel())
		{
			Result = EVisibility::Visible;
		}
	}
	return Result;
}
Пример #12
0
/** Restores systems that need references to classes in the renderer module. */
void RestoreReferencesToRendererModuleClasses(
    const TMap<UWorld*, bool>& WorldsToUpdate,
    const TMap<FMaterialShaderMap*, TScopedPointer<TArray<uint8> > >& ShaderMapToSerializedShaderData,
    const TScopedPointer<TArray<uint8> >& GlobalShaderData,
    const TMap<FShaderType*, FString>& ShaderTypeNames,
    const TMap<FVertexFactoryType*, FString>& VertexFactoryTypeNames)
{
    FlushShaderFileCache();

    // Initialize cached shader type data
    InitializeShaderTypes();

    IRendererModule& RendererModule = GetRendererModule();

    FSceneViewStateReference::AllocateAll();

    // Recreate all renderer scenes
    for (TMap<UWorld*, bool>::TConstIterator It(WorldsToUpdate); It; ++It)
    {
        UWorld* World = It.Key();

        RendererModule.AllocateScene(World, World->RequiresHitProxies(), It.Value(), World->FeatureLevel);

        for (int32 LevelIndex = 0; LevelIndex < World->GetNumLevels(); LevelIndex++)
        {
            ULevel* Level = World->GetLevel(LevelIndex);
            Level->InitializeRenderingResources();
        }
    }

    // Restore FShaders from the serialized memory blobs
    // Shader maps may still not be complete after this due to code changes picked up in the recompile
    RestoreGlobalShaderMap(GRHIShaderPlatform_DEPRECATED, *GlobalShaderData);
    UMaterial::RestoreMaterialShadersFromMemory(GRHIShaderPlatform_DEPRECATED, ShaderMapToSerializedShaderData);
    FMaterialShaderMap::FixupShaderTypes(GRHIShaderPlatform_DEPRECATED, ShaderTypeNames, VertexFactoryTypeNames);

    TArray<FShaderType*> OutdatedShaderTypes;
    TArray<const FVertexFactoryType*> OutdatedFactoryTypes;
    FShaderType::GetOutdatedTypes(OutdatedShaderTypes, OutdatedFactoryTypes);

    // Recompile any missing shaders
    UMaterialInterface::IterateOverActiveFeatureLevels([&](ERHIFeatureLevel::Type FeatureLevel)
    {
        auto ShaderPlatform = GShaderPlatformForFeatureLevel[FeatureLevel];
        BeginRecompileGlobalShaders(OutdatedShaderTypes, ShaderPlatform);
        UMaterial::UpdateMaterialShaders(OutdatedShaderTypes, OutdatedFactoryTypes, ShaderPlatform);
    });

    // Block on global shader jobs
    FinishRecompileGlobalShaders();
}
Пример #13
0
/**
* 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 );
            }
        }
    }
}
Пример #14
0
TArray<UPackage*> FLevelCollectionModel::GetPackagesList(const FLevelModelList& InList)
{
	TArray<UPackage*> ResultList;
	
	for (auto It = InList.CreateConstIterator(); It; ++It)
	{
		ULevel* Level = (*It)->GetLevelObject();
		if (Level)
		{
			ResultList.Add(Level->GetOutermost());
		}
	}

	return ResultList;
}
Пример #15
0
void FWorldTileModel::SetLevelPosition(const FIntPoint& InPosition)
{
	// Parent absolute position
	TSharedPtr<FWorldTileModel> ParentModel = StaticCastSharedPtr<FWorldTileModel>(GetParent());
	FIntPoint ParentAbsolutePostion = ParentModel.IsValid() ? ParentModel->GetAbsoluteLevelPosition() : FIntPoint::ZeroValue;
	
	// Actual offset
	FIntPoint Offset = InPosition - TileDetails->AbsolutePosition;
	
	// Update absolute position
	TileDetails->AbsolutePosition = InPosition;

	// Assign new position as relative to parent
	TileDetails->Position = TileDetails->AbsolutePosition - ParentAbsolutePostion;
	
	// Flush changes to level package
	OnLevelInfoUpdated();
	
	// Move actors if necessary
	ULevel* Level = GetLevelObject();
	if (Level != NULL && Level->bIsVisible)
	{
		// Shelve level, if during this translation level will end up out of Editable area
		if (!ShouldBeVisible(LevelCollectionModel.EditableWorldArea()))
		{
			Shelve();
		}
		
		// Move actors
		if (Offset != FIntPoint::ZeroValue)
		{
			Level->ApplyWorldOffset(FVector(Offset), false);
		}
	}

	if (IsLandscapeBased())
	{
		FixLandscapeSectionsOffset();
	}
	
	// Transform child levels
	for (auto It = AllChildren.CreateIterator(); It; ++It)
	{
		TSharedPtr<FWorldTileModel> ChildModel = StaticCastSharedPtr<FWorldTileModel>(*It);
		FIntPoint ChildPosition = TileDetails->AbsolutePosition + ChildModel->GetRelativeLevelPosition();
		ChildModel->SetLevelPosition(ChildPosition);
	}
}
Пример #16
0
FString FLevelModel::GetFileSizeString() const
{
	FString MemorySizeString;
	ULevel* Level = GetLevelObject();

	if (Level && Editor->AccessEditorUserSettings().bDisplayFileSizeInLevelBrowser)
	{
		// Update metrics
		static const float ByteConversion = 1.0f / 1024.0f;
		float FileSize = Level->GetOutermost()->GetFileSize() * ByteConversion * ByteConversion;
		
		MemorySizeString += FString::Printf(TEXT( "%.2f" ), FileSize);
	}

	return MemorySizeString;
}
Пример #17
0
FString FLevelViewModel::GetFileSizeString() const
{
	FString MemorySizeString;
	ULevel* CurLevel = Level.Get();

	if ( CurLevel && GetDefault<ULevelBrowserSettings>()->bDisplayFileSize  )
	{
		// Update metrics
		static const float ByteConversion = 1.0f / 1024.0f;
		float FileSize = CurLevel->GetOutermost()->GetFileSize() * ByteConversion * ByteConversion;
		
		MemorySizeString += FString::Printf( TEXT( "%.2f" ), FileSize );
	}

	return MemorySizeString;
}
Пример #18
0
void FLevelCollectionModel::CacheCanExecuteSourceControlVars() const
{
	bCanExecuteSCCCheckOut = false;
	bCanExecuteSCCOpenForAdd = false;
	bCanExecuteSCCCheckIn = false;
	bCanExecuteSCC = false;

	ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider();
	for (auto It = SelectedLevelsList.CreateConstIterator(); It; ++It)
	{
		if (ISourceControlModule::Get().IsEnabled() && SourceControlProvider.IsAvailable())
		{
			bCanExecuteSCC = true;
			
			ULevel* Level = (*It)->GetLevelObject();
			if (Level)
			{
				// Check the SCC state for each package in the selected paths
				FSourceControlStatePtr SourceControlState = SourceControlProvider.GetState(Level->GetOutermost(), EStateCacheUsage::Use);

				if (SourceControlState.IsValid())
				{
					if (SourceControlState->CanCheckout())
					{
						bCanExecuteSCCCheckOut = true;
					}
					else if (!SourceControlState->IsSourceControlled())
					{
						bCanExecuteSCCOpenForAdd = true;
					}
					else if (SourceControlState->IsCheckedOut() || SourceControlState->IsAdded())
					{
						bCanExecuteSCCCheckIn = true;
					}
				}
			}
		}

		if (bCanExecuteSCCCheckOut && 
			bCanExecuteSCCOpenForAdd && 
			bCanExecuteSCCCheckIn)
		{
			// All options are available, no need to keep iterating
			break;
		}
	}
}
Пример #19
0
void FLevelViewModel::ChangeColor(const TSharedRef<SWidget>& InPickerParentWidget)
{
	if( !Level.IsValid() )
	{
		return;
	}

	if ( !Level->IsPersistentLevel())
	{
		// Initialize the color data for the picker window.
		ULevelStreaming* StreamingLevel = FLevelUtils::FindStreamingLevel( Level.Get() );
		check( StreamingLevel );

		FLinearColor NewColor = StreamingLevel->LevelColor;
		TArray<FLinearColor*> ColorArray;
		ColorArray.Add(&NewColor);

		FColorPickerArgs PickerArgs;
		PickerArgs.bIsModal = true;
		PickerArgs.DisplayGamma = TAttribute<float>::Create( TAttribute<float>::FGetter::CreateUObject(GEngine, &UEngine::GetDisplayGamma) );
		PickerArgs.LinearColorArray = &ColorArray;
		PickerArgs.OnColorPickerCancelled = FOnColorPickerCancelled::CreateSP(this, &FLevelViewModel::OnColorPickerCancelled);
		PickerArgs.ParentWidget = InPickerParentWidget;

		// ensure this is true, will be set to false in OnColorPickerCancelled if necessary
		bColorPickerOK = true;
		if (OpenColorPicker(PickerArgs))
		{
			if ( bColorPickerOK )
			{
				StreamingLevel->LevelColor = NewColor;
				StreamingLevel->Modify();

				// Update the loaded level's components so the change in color will apply immediately
				ULevel* LoadedLevel = StreamingLevel->GetLoadedLevel();
				if ( LoadedLevel )
				{
					LoadedLevel->UpdateLevelComponents(false);
				}

				ULevel::LevelDirtiedEvent.Broadcast();
			}
			FEditorSupportDelegates::RedrawAllViewports.Broadcast();
		}
	}
}
Пример #20
0
	/** Check if the object is in a visible level */
	bool IsInVisibleLevel( UObject* InObject, UWorld* InWorld ) const
	{
		check( InObject );
		check( InWorld );

		UObject* ObjectPackage = InObject->GetOutermost();

		for( int32 LevelIndex=0; LevelIndex<InWorld->GetNumLevels(); LevelIndex++ )
		{
			ULevel* Level = InWorld->GetLevel(LevelIndex);
			if( Level && Level->GetOutermost() == ObjectPackage )
			{
				return true;
			}
		}
		return false;
	}
Пример #21
0
void UUnrealEdEngine::ConvertMatinees()
{
	FVector StartLocation= FVector::ZeroVector;
	UWorld* World = GWorld;
	if( World )
	{
		ULevel* Level = World->GetCurrentLevel();
		if( !Level )
		{
			Level = World->PersistentLevel;
		}
		check(Level);
		for( TObjectIterator<UInterpData> It; It; ++It )
		{
			UInterpData* InterpData = *It;
			if( InterpData->IsIn( Level ) ) 
			{
				// We dont care about renaming references or adding redirectors.  References to this will be old seqact_interps
				GEditor->RenameObject( InterpData, Level->GetOutermost(), *InterpData->GetName() );

				AMatineeActor* MatineeActor = Level->OwningWorld->SpawnActor<AMatineeActor>(StartLocation, FRotator::ZeroRotator);
				StartLocation.Y += 50;
								
				MatineeActor->MatineeData = InterpData;
				UProperty* MatineeDataProp = NULL;
				for( UProperty* Property = MatineeActor->GetClass()->PropertyLink; Property != NULL; Property = Property->PropertyLinkNext )
				{
					if( Property->GetName() == TEXT("MatineeData") )
					{
						MatineeDataProp = Property;
						break;
					}
				}

				FPropertyChangedEvent PropertyChangedEvent( MatineeDataProp ); 
				MatineeActor->PostEditChangeProperty( PropertyChangedEvent );
			}
		}
	}

}
Пример #22
0
void FLevelModel::OpenKismet()
{
	if (LevelCollectionModel.IsReadOnly())
	{
		return;
	}
	
	ULevel* Level = GetLevelObject();

	if (Level == NULL)
	{
		return;
	}
	
	ULevelScriptBlueprint* LevelScriptBlueprint = Level->GetLevelScriptBlueprint();
	if (LevelScriptBlueprint)
	{
		FAssetEditorManager::Get().OpenEditorForAsset(LevelScriptBlueprint);
	}
	else
	{
		FMessageDialog::Open(EAppMsgType::Ok, NSLOCTEXT("UnrealEd", "UnableToCreateLevelScript", "Unable to find or create a level blueprint for this level.") );
	}
}
Пример #23
0
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);
		}
	}
}
ENGINE_API bool BuildTextureStreamingData(UWorld* InWorld, const FTexCoordScaleMap& InTexCoordScales, EMaterialQualityLevel::Type QualityLevel, ERHIFeatureLevel::Type FeatureLevel, FSlowTask& BuildTextureStreamingTask)
{
#if WITH_EDITORONLY_DATA
    if (!InWorld) return false;
    const double StartTime = FPlatformTime::Seconds();

    // ====================================================
    // Build per primitive data
    // ====================================================
    const float NumPrimitiveComponents = (float)GetNumTextureStreamingPrimitives(InWorld);
    FScopedSlowTask SlowTask(NumPrimitiveComponents, (LOCTEXT("TextureStreamingBuild_ComponentDataUpdate", "Updating Component Data")));

    for (int32 LevelIndex = 0; LevelIndex < InWorld->GetNumLevels(); LevelIndex++)
    {
        ULevel* Level = InWorld->GetLevel(LevelIndex);
        if (!Level) continue;

        TArray<UTexture2D*> LevelTextures;

        TArray<UPrimitiveComponent*> Components;
        GetTextureStreamingPrimitives(Level, Components, false);
        for (UPrimitiveComponent* Primitive : Components)
        {
            // Update all primitives as this could clear unwanted data.
            Primitive->UpdateStreamingTextureData(LevelTextures, InTexCoordScales, QualityLevel, FeatureLevel);

            if (Primitive->RequiresStreamingTextureData())
            {
                // Slow task only accounts for primitive having streaming data.
                SlowTask.EnterProgressFrame();
                BuildTextureStreamingTask.EnterProgressFrame(1.f / NumPrimitiveComponents);

                if (GWarn->ReceivedUserCancel())
                    return false;

                UStaticMeshComponent* StaticMeshComponent = Cast<UStaticMeshComponent>(Primitive);
                if (StaticMeshComponent && StaticMeshComponent->StaticMesh && StaticMeshComponent->StaticMesh->GetLightingGuid().IsValid())
                {
                    // Add to the build Guids all used static meshes.
                    Level->TextureStreamingBuildGuids.Add(StaticMeshComponent->StaticMesh->GetLightingGuid());
                }
            }
        }

        // If a component was updated, or  the level data needs reset.
        if (Level->bTextureStreamingRotationChanged || Level->StreamingTextureGuids.Num() || LevelTextures.Num())
        {
            Level->bTextureStreamingRotationChanged = false;
            Level->StreamingTextureGuids.Empty(LevelTextures.Num());
            Level->MarkPackageDirty();

            // Reset LevelIndex to default for next use and build the level Guid array.
            for (int32 TextureIndex = 0; TextureIndex < LevelTextures.Num(); ++TextureIndex)
            {
                UTexture2D* Texture2D = LevelTextures[TextureIndex];
                Level->StreamingTextureGuids.Push(Texture2D->GetLightingGuid());
                Texture2D->LevelIndex = INDEX_NONE;
            }
        }
    }

    // ====================================================
    // Update texture streaming data
    // ====================================================

    ULevel::BuildStreamingData(InWorld);

    // ====================================================
    // Reregister everything for debug view modes to reflect changes
    // ====================================================

    for (int32 LevelIndex = 0; LevelIndex < InWorld->GetNumLevels(); LevelIndex++)
    {
        ULevel* Level = InWorld->GetLevel(LevelIndex);
        if (!Level) continue;
        for (AActor* Actor : Level->Actors)
        {
            if (!Actor) continue;
            Actor->MarkComponentsRenderStateDirty();
        }
    }
    UE_LOG(TextureStreamingBuild, Display, TEXT("Build Texture Streaming took %.3f seconds."), FPlatformTime::Seconds() - StartTime);
    return true;
#else
    UE_LOG(TextureStreamingBuild, Fatal,TEXT("Build Texture Streaming should not be called on a console"));
    return false;
#endif
}
Пример #25
0
bool FEditorBuildUtils::EditorAutomatedBuildAndSubmit( const FEditorAutomatedBuildSettings& BuildSettings, FText& OutErrorMessages )
{
	// Assume the build is successful to start
	bool bBuildSuccessful = true;
	
	// Keep a set of packages that should be submitted to source control at the end of a successful build. The build preparation and processing
	// will add and remove from the set depending on build settings, errors, etc.
	TSet<UPackage*> PackagesToSubmit;

	// Perform required preparations for the automated build process
	bBuildSuccessful = PrepForAutomatedBuild( BuildSettings, PackagesToSubmit, OutErrorMessages );

	// If the preparation went smoothly, attempt the actual map building process
	if ( bBuildSuccessful )
	{
		bBuildSuccessful = EditorBuild( GWorld, EBuildOptions::BuildAllSubmit );

		// If the map build failed, log the error
		if ( !bBuildSuccessful )
		{
			LogErrorMessage( NSLOCTEXT("UnrealEd", "AutomatedBuild_Error_BuildFailed", "The map build failed or was canceled."), OutErrorMessages );
		}
	}

	// If any map errors resulted from the build, process them according to the behavior specified in the build settings
	if ( bBuildSuccessful && FMessageLog("MapCheck").NumMessages( EMessageSeverity::Warning ) > 0 )
	{
		bBuildSuccessful = ProcessAutomatedBuildBehavior( BuildSettings.BuildErrorBehavior, NSLOCTEXT("UnrealEd", "AutomatedBuild_Error_MapErrors", "Map errors occurred while building.\n\nAttempt to continue the build?"), OutErrorMessages );
	}

	// If it's still safe to proceed, attempt to save all of the level packages that have been marked for submission
	if ( bBuildSuccessful )
	{
		UPackage* CurOutermostPkg = GWorld->PersistentLevel->GetOutermost();
		FString PackagesThatFailedToSave;

		// Try to save the p-level if it should be submitted
		if ( PackagesToSubmit.Contains( CurOutermostPkg ) && !FEditorFileUtils::SaveLevel( GWorld->PersistentLevel ) )
		{
			// If the p-level failed to save, remove it from the set of packages to submit
			PackagesThatFailedToSave += FString::Printf( TEXT("%s\n"), *CurOutermostPkg->GetName() );
			PackagesToSubmit.Remove( CurOutermostPkg );
		}
		
		// Try to save each streaming level (if they should be submitted)
		for ( TArray<ULevelStreaming*>::TIterator LevelIter( GWorld->StreamingLevels ); LevelIter; ++LevelIter )
		{
			ULevelStreaming* CurStreamingLevel = *LevelIter;
			if ( CurStreamingLevel != NULL )
			{
				ULevel* Level = CurStreamingLevel->GetLoadedLevel();
				if ( Level != NULL )
				{
					CurOutermostPkg = Level->GetOutermost();
					if ( PackagesToSubmit.Contains( CurOutermostPkg ) && !FEditorFileUtils::SaveLevel( Level ) )
					{
						// If a save failed, remove the streaming level from the set of packages to submit
						PackagesThatFailedToSave += FString::Printf( TEXT("%s\n"), *CurOutermostPkg->GetName() );
						PackagesToSubmit.Remove( CurOutermostPkg );
					}
				}
			}
		}

		// If any packages failed to save, process the behavior specified by the build settings to see how the process should proceed
		if ( PackagesThatFailedToSave.Len() > 0 )
		{
			bBuildSuccessful = ProcessAutomatedBuildBehavior( BuildSettings.FailedToSaveBehavior,
				FText::Format( NSLOCTEXT("UnrealEd", "AutomatedBuild_Error_FilesFailedSave", "The following assets failed to save and cannot be submitted:\n\n{0}\n\nAttempt to continue the build?"), FText::FromString(PackagesThatFailedToSave) ),
				OutErrorMessages );
		}
	}

	// If still safe to proceed, make sure there are actually packages remaining to submit
	if ( bBuildSuccessful )
	{
		bBuildSuccessful = PackagesToSubmit.Num() > 0;
		if ( !bBuildSuccessful )
		{
			LogErrorMessage( NSLOCTEXT("UnrealEd", "AutomatedBuild_Error_NoValidLevels", "None of the current levels are valid for submission; automated build aborted."), OutErrorMessages );
		}
	}

	// Finally, if everything has gone smoothly, submit the requested packages to source control
	if ( bBuildSuccessful )
	{
		SubmitPackagesForAutomatedBuild( PackagesToSubmit, BuildSettings );
	}

	// Check if the user requested the editor shutdown at the conclusion of the automated build
	if ( BuildSettings.bShutdownEditorOnCompletion )
	{
		FPlatformMisc::RequestExit( false );
	}

	return bBuildSuccessful;
}
Пример #26
0
void FShadowMapPendingTexture::StartEncoding(UWorld* InWorld)
{
	// Create the shadow-map texture.
	UShadowMapTexture2D* Texture = new(Outer) UShadowMapTexture2D(FPostConstructInitializeProperties());
	Texture->Filter			= GUseBilinearLightmaps ? TF_Default : TF_Nearest;
	// Signed distance field textures get stored in linear space, since they need more precision near .5.
	Texture->SRGB			= false;
	Texture->LODGroup		= TEXTUREGROUP_Shadowmap;
	Texture->ShadowmapFlags	= ShadowmapFlags;
	Texture->Source.Init2DWithMipChain(GetSizeX(), GetSizeY(), TSF_BGRA8);
	Texture->MipGenSettings = TMGS_LeaveExistingMips;
	Texture->CompressionNone = true;

	int32 TextureSizeX = Texture->Source.GetSizeX();
	int32 TextureSizeY = Texture->Source.GetSizeY();

	{
		// Create the uncompressed top mip-level.
		TArray< TArray<FFourDistanceFieldSamples> > MipData;
		FShadowMap2D::EncodeSingleTexture(*this, Texture, MipData);

		// Copy the mip-map data into the UShadowMapTexture2D's mip-map array.
		for(int32 MipIndex = 0;MipIndex < MipData.Num();MipIndex++)
		{
			FColor* DestMipData = (FColor*)Texture->Source.LockMip(MipIndex);
			uint32 MipSizeX = FMath::Max(1,TextureSizeX >> MipIndex);
			uint32 MipSizeY = FMath::Max(1,TextureSizeY >> MipIndex);

			for(uint32 Y = 0;Y < MipSizeY;Y++)
			{
				for(uint32 X = 0;X < MipSizeX;X++)
				{
					const FFourDistanceFieldSamples& SourceSample = MipData[MipIndex][Y * MipSizeX + X];
					DestMipData[ Y * MipSizeX + X ] = FColor(SourceSample.Samples[0].Distance, SourceSample.Samples[1].Distance, SourceSample.Samples[2].Distance, SourceSample.Samples[3].Distance);
				}
			}

			Texture->Source.UnlockMip(MipIndex);
		}
	}

	// Update stats.
	int32 TextureSize			= Texture->CalcTextureMemorySizeEnum( TMC_AllMips );
	GNumShadowmapTotalTexels	+= TextureSizeX * TextureSizeY;
	GNumShadowmapTextures++;
	GShadowmapTotalSize			+= TextureSize;
	GShadowmapTotalStreamingSize += (ShadowmapFlags & SMF_Streamed) ? TextureSize : 0;
	UPackage* TexturePackage = Texture->GetOutermost();

	for ( int32 LevelIndex=0; TexturePackage && LevelIndex < InWorld->GetNumLevels(); LevelIndex++ )
	{
		ULevel* Level = InWorld->GetLevel(LevelIndex);
		UPackage* LevelPackage = Level->GetOutermost();
		if ( TexturePackage == LevelPackage )
		{
			Level->ShadowmapTotalSize += float(TextureSize) / 1024.0f;
			break;
		}
	}

	// Update the texture resource.
	Texture->BeginCachePlatformData();
	Texture->FinishCachePlatformData();
	Texture->UpdateResource();
}
Пример #27
0
void FLevelCollectionModel::SaveLevels(const FLevelModelList& InLevelList)
{
	if (IsReadOnly())
	{
		return;
	}

		
	FLevelModelList		LevelModelsToSave;
	TArray<ULevel*>		LevelsToSave;
	for (auto It = InLevelList.CreateConstIterator(); It; ++It)
	{
		if ((*It)->GetLevelObject())
		{
			if (!(*It)->IsVisible())
			{
				FMessageDialog::Open( EAppMsgType::Ok, NSLOCTEXT("UnrealEd", "UnableToSaveInvisibleLevels", "Save aborted.  Levels must be made visible before they can be saved.") );
				return;
			}
			else if ((*It)->IsLocked())
			{
				FMessageDialog::Open( EAppMsgType::Ok, NSLOCTEXT("UnrealEd", "UnableToSaveLockedLevels", "Save aborted.  Level must be unlocked before it can be saved.") );
				return;
			}
						
			LevelModelsToSave.Add(*It);
			LevelsToSave.Add((*It)->GetLevelObject());
		}
	}

	TArray< UPackage* > PackagesNotNeedingCheckout;
	// Prompt the user to check out the levels from source control before saving
	if (FEditorFileUtils::PromptToCheckoutLevels(false, LevelsToSave, &PackagesNotNeedingCheckout))
	{
		for (auto It = LevelsToSave.CreateIterator(); It; ++It)
		{
			FEditorFileUtils::SaveLevel(*It);
		}
	}
	else if (PackagesNotNeedingCheckout.Num() > 0)
	{
		// The user canceled the checkout dialog but some packages didn't need to be checked out in order to save
		// For each selected level if the package its in didn't need to be saved, save the level!
		for (int32 LevelIdx = 0; LevelIdx < LevelsToSave.Num(); ++LevelIdx)
		{
			ULevel* Level = LevelsToSave[LevelIdx];
			if (PackagesNotNeedingCheckout.Contains(Level->GetOutermost()))
			{
				FEditorFileUtils::SaveLevel(Level);
			}
			else
			{
				//remove it from the list, so that only successfully saved levels are highlighted when saving is complete
				LevelModelsToSave.RemoveAt(LevelIdx);
				LevelsToSave.RemoveAt(LevelIdx);
			}
		}
	}

	// Select tiles that were saved successfully
	SetSelectedLevels(LevelModelsToSave);
}
Пример #28
0
/** This will set the StreamingLevels TMap with the current Streaming Level Status and also set which level the player is in **/
void GetLevelStreamingStatus( UWorld* World, TMap<FName,int32>& StreamingLevels, FString& LevelPlayerIsInName )
{
	FWorldContext &Context = GEngine->WorldContextFromWorld(World);

	// Iterate over the world info's level streaming objects to find and see whether levels are loaded, visible or neither.
	for( int32 LevelIndex=0; LevelIndex<World->StreamingLevels.Num(); LevelIndex++ )
	{
		ULevelStreaming* LevelStreaming = World->StreamingLevels[LevelIndex];

		if( LevelStreaming 
			&&  LevelStreaming->PackageName != NAME_None 
			&&	LevelStreaming->PackageName != World->GetOutermost()->GetFName() )
		{
			ULevel* Level = LevelStreaming->GetLoadedLevel();
			if( Level != NULL )
			{
				if( World->ContainsLevel( Level ) == true )
				{
					if( World->CurrentLevelPendingVisibility == Level )
					{
						StreamingLevels.Add( LevelStreaming->PackageName, LEVEL_MakingVisible );
					}
					else
					{
						StreamingLevels.Add( LevelStreaming->PackageName, LEVEL_Visible );
					}
				}
				else
				{
					StreamingLevels.Add( LevelStreaming->PackageName, LEVEL_Loaded );
				}
			}
			else
			{
				// See whether the level's world object is still around.
				UPackage* LevelPackage	= Cast<UPackage>(StaticFindObjectFast( UPackage::StaticClass(), NULL, LevelStreaming->PackageName ));
				UWorld*	  LevelWorld	= NULL;
				if( LevelPackage )
				{
					LevelWorld = UWorld::FindWorldInPackage(LevelPackage);
				}

				if( LevelWorld )
				{
					StreamingLevels.Add( LevelStreaming->PackageName, LEVEL_UnloadedButStillAround );
				}
				else if( GetAsyncLoadPercentage( *LevelStreaming->PackageName.ToString() ) >= 0 )
				{
					StreamingLevels.Add( LevelStreaming->PackageName, LEVEL_Loading );
				}
				else
				{
					StreamingLevels.Add( LevelStreaming->PackageName, LEVEL_Unloaded );
				}
			}
		}
	}

	
	// toss in the levels being loaded by PrepareMapChange
	for( int32 LevelIndex=0; LevelIndex < Context.LevelsToLoadForPendingMapChange.Num(); LevelIndex++ )
	{
		const FName LevelName = Context.LevelsToLoadForPendingMapChange[LevelIndex];
		StreamingLevels.Add(LevelName, LEVEL_Preloading);
	}


	ULevel* LevelPlayerIsIn = NULL;

	for( FConstPlayerControllerIterator Iterator = World->GetPlayerControllerIterator(); Iterator; ++Iterator )
	{
		APlayerController* PlayerController = *Iterator;

		if( PlayerController->GetPawn() != NULL )
		{
			// need to do a trace down here
			//TraceActor = Trace( out_HitLocation, out_HitNormal, TraceDest, TraceStart, false, TraceExtent, HitInfo, true );
			FHitResult Hit(1.f);

			// this will not work for flying around :-(
			static FName NAME_FindLevel = FName(TEXT("FindLevel"), true);			
			PlayerController->GetWorld()->LineTraceSingle(Hit,PlayerController->GetPawn()->GetActorLocation(), (PlayerController->GetPawn()->GetActorLocation()-FVector(0.f, 0.f, 256.f)), FCollisionQueryParams(NAME_FindLevel, true, PlayerController->GetPawn()), FCollisionObjectQueryParams(ECC_WorldStatic));

			/** @todo UE4 FIXME
			if( Hit.Level != NULL )
			{
				LevelPlayerIsIn = Hit.Level;
			}
			else 
			*/
			if( Hit.GetActor() != NULL )
			{
				LevelPlayerIsIn = Hit.GetActor()->GetLevel();
			}
			else if( Hit.Component != NULL && Hit.Component->GetOwner() != NULL )
			{
				AActor* Owner = Hit.Component->GetOwner();
				if (Owner)
				{
					LevelPlayerIsIn = Owner->GetLevel();
				}
				else
				{
					// This happens for BSP where the ModelComponent's outer is the level
					LevelPlayerIsIn = Hit.Component->GetTypedOuter<ULevel>();
				}
			}
		}
	}

	// this no longer seems to be getting the correct level name :-(
	LevelPlayerIsInName = LevelPlayerIsIn != NULL ? LevelPlayerIsIn->GetOutermost()->GetName() : TEXT("None");
}
Пример #29
0
void FLevelCollectionModel::SCCDiffAgainstDepot(const FLevelModelList& InList, UEditorEngine* InEditor)
{
	// Load the asset registry module
	FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools");

	ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider();

	// Iterate over each selected asset
	for (auto It = InList.CreateConstIterator(); It; ++It)
	{
		ULevel* Level = (*It)->GetLevelObject();
		if (Level == NULL)
		{
			return;
		}
		
		UPackage* OriginalPackage = Level->GetOutermost();
		FString PackageName = OriginalPackage->GetName();

		// Make sure our history is up to date
		auto UpdateStatusOperation = ISourceControlOperation::Create<FUpdateStatus>();
		UpdateStatusOperation->SetUpdateHistory(true);
		SourceControlProvider.Execute(UpdateStatusOperation, OriginalPackage);

		// Get the SCC state
		FSourceControlStatePtr SourceControlState = SourceControlProvider.GetState(
			OriginalPackage, EStateCacheUsage::Use
			);

		// If the level is in SCC.
		if (SourceControlState.IsValid() && SourceControlState->IsSourceControlled())
		{
			// Get the file name of package
			FString RelativeFileName;
			if(FPackageName::DoesPackageExist(PackageName, NULL, &RelativeFileName))
			{
				if (SourceControlState->GetHistorySize() > 0)
				{
					auto Revision = SourceControlState->GetHistoryItem(0);
					check(Revision.IsValid());

					// Get the head revision of this package from source control
					FString AbsoluteFileName = FPaths::ConvertRelativePathToFull(RelativeFileName);
					FString TempFileName;
					if (Revision->Get(TempFileName))
					{
						// Forcibly disable compile on load in case we are loading old blueprints that might try to update/compile
						TGuardValue<bool> DisableCompileOnLoad(GForceDisableBlueprintCompileOnLoad, true);

						// Try and load that package
						FText NotMapReason;
						UPackage* OldPackage = LoadPackage(NULL, *TempFileName, LOAD_None);
						if(OldPackage != NULL && InEditor->PackageIsAMapFile(*TempFileName, NotMapReason))
						{
							/* Set the revision information*/
							UPackage* Package = OriginalPackage;

							FRevisionInfo OldRevision;
							OldRevision.Changelist = Revision->GetCheckInIdentifier();
							OldRevision.Date = Revision->GetDate();
							OldRevision.Revision = Revision->GetRevision();

							FRevisionInfo NewRevision; 
							NewRevision.Revision = TEXT("");

							// Dump assets to temp text files
							FString OldTextFilename = AssetToolsModule.Get().DumpAssetToTempFile(OldPackage);
							FString NewTextFilename = AssetToolsModule.Get().DumpAssetToTempFile(OriginalPackage);
							FString DiffCommand = GetDefault<UEditorLoadingSavingSettings>()->TextDiffToolPath.FilePath;

							AssetToolsModule.Get().CreateDiffProcess(DiffCommand, OldTextFilename, NewTextFilename);
							AssetToolsModule.Get().DiffAssets(OldPackage, OriginalPackage, OldRevision, NewRevision);
						}
					}
				}
			} 
		}
	}
}
Пример #30
0
/** Clears and optionally backs up all references to renderer module classes in other modules, particularly engine. */
void ClearReferencesToRendererModuleClasses(
    TMap<UWorld*, bool>& WorldsToUpdate,
    TMap<FMaterialShaderMap*, TScopedPointer<TArray<uint8> > >& ShaderMapToSerializedShaderData,
    TScopedPointer<TArray<uint8> >& GlobalShaderData,
    TMap<FShaderType*, FString>& ShaderTypeNames,
    TMap<FVertexFactoryType*, FString>& VertexFactoryTypeNames)
{
    // Destroy all renderer scenes
    for (TObjectIterator<UWorld> WorldIt; WorldIt; ++WorldIt)
    {
        UWorld* World = *WorldIt;

        if (World->Scene)
        {
            WorldsToUpdate.Add(World, World->FXSystem != NULL);

            for (int32 LevelIndex = 0; LevelIndex < World->GetNumLevels(); LevelIndex++)
            {
                ULevel* Level = World->GetLevel(LevelIndex);
                Level->ReleaseRenderingResources();
            }

            if (World->FXSystem != NULL)
            {
                FFXSystemInterface::Destroy(World->FXSystem);
                World->FXSystem = NULL;
            }

            World->Scene->Release();
            World->Scene = NULL;
        }
    }

    // Save off shaders by serializing them into memory, and remove all shader map references to FShaders
    GlobalShaderData = TScopedPointer<TArray<uint8> >(BackupGlobalShaderMap(GRHIShaderPlatform_DEPRECATED));
    UMaterial::BackupMaterialShadersToMemory(ShaderMapToSerializedShaderData);

    // Verify no FShaders still in memory
    for(TLinkedList<FShaderType*>::TIterator It(FShaderType::GetTypeList()); It; It.Next())
    {
        FShaderType* ShaderType = *It;
        check(ShaderType->GetNumShaders() == 0);
        ShaderTypeNames.Add(ShaderType, ShaderType->GetName());
    }

    for(TLinkedList<FVertexFactoryType*>::TIterator It(FVertexFactoryType::GetTypeList()); It; It.Next())
    {
        FVertexFactoryType* VertexFactoryType = *It;
        VertexFactoryTypeNames.Add(VertexFactoryType, VertexFactoryType->GetName());
    }

    // Destroy misc renderer module classes and remove references
    FSceneViewStateReference::DestroyAll();
    FSlateApplication::Get().InvalidateAllViewports();

    // Invalidate cached shader type data
    UninitializeShaderTypes();

    // Delete pending cleanup objects to remove those references, which are potentially renderer module classes
    FPendingCleanupObjects* PendingCleanupObjects = GetPendingCleanupObjects();
    delete PendingCleanupObjects;
    GEngine->EngineLoop->ClearPendingCleanupObjects();

    ResetCachedRendererModule();
}