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); } } }
bool FLevelModel::IsDirty() const { if (GetLevelObject()) { return GetLevelObject()->GetOutermost()->IsDirty(); } return false; }
bool FLevelModel::IsCurrent() const { if (GetLevelObject()) { return GetLevelObject()->IsCurrentLevel(); } return false; }
void FWorldTileModel::SetAlwaysLoaded(bool bAlwaysLoaded) { if (LevelCollectionModel.IsReadOnly() || GetLevelObject() == NULL || IsRootTile()) { return; } FWorldTileInfo Info = LevelCollectionModel.GetWorld()->WorldComposition->GetTileInfo(TileDetails->PackageName); if (Info.bAlwaysLoaded != bAlwaysLoaded) { bool bWasVisible = GetLevelObject()->bIsVisible; // Hide level, so it will be positioned at origin SetVisible(false); auto& WorldModel = static_cast<FWorldTileCollectionModel&>(LevelCollectionModel); TSharedPtr<FWorldTileModel> RootTileModel = WorldModel.GetWorldRootModel(); // Remove parent relationship AttachTo(RootTileModel); // Detach children for (auto It = AllChildren.CreateConstIterator(); It; ++It) { (*It)->AttachTo(RootTileModel); } //Remove world positioning TileDetails->Position = FIntPoint::ZeroValue; TileDetails->AbsolutePosition = FIntPoint::ZeroValue; //Mark level TileDetails->bAlwaysLoaded = bAlwaysLoaded; OnLevelInfoUpdated(); // Restore level visibility if (bAlwaysLoaded) { // Always loaded levels - always visible SetVisible(true); } else { SetVisible(bWasVisible); } } }
void FLevelModel::MakeLevelCurrent() { if (LevelCollectionModel.IsReadOnly()) { return; } if (!IsLoaded()) { // Load level from disk FLevelModelList LevelsList; LevelsList.Add(this->AsShared()); LevelCollectionModel.LoadLevels(LevelsList); } ULevel* Level = GetLevelObject(); if (Level == NULL) { return; } // Locked levels can't be made current. if (!FLevelUtils::IsLevelLocked(Level)) { // Make current. if (LevelCollectionModel.GetWorld()->SetCurrentLevel(Level)) { FEditorDelegates::NewCurrentLevel.Broadcast(); // Deselect all selected builder brushes. bool bDeselectedSomething = false; for (FSelectionIterator It(Editor->GetSelectedActorIterator()); It; ++It) { AActor* Actor = static_cast<AActor*>(*It); checkSlow(Actor->IsA(AActor::StaticClass())); ABrush* Brush = Cast< ABrush >( Actor ); if (Brush && FActorEditorUtils::IsABuilderBrush(Brush)) { Editor->SelectActor(Actor, /*bInSelected=*/ false, /*bNotify=*/ false); bDeselectedSomething = true; } } // Send a selection change callback if necessary. if (bDeselectedSomething) { Editor->NoteSelectionChange(); } } // Force the current level to be visible. SetVisible(true); } else { FMessageDialog::Open(EAppMsgType::Ok, NSLOCTEXT("UnrealEd", "Error_OperationDisallowedOnLockedLevelMakeLevelCurrent", "MakeLevelCurrent: The requested operation could not be completed because the level is locked.")); } Update(); }
void FLevelModel::UpdateLevelActorsCount() { LevelActorsCount = 0; ULevel* Level = GetLevelObject(); if (Level) { // Count the actors contained in these levels // NOTE: We subtract two here to omit "default actors" in the count (default brush, and WorldSettings) LevelActorsCount = Level->Actors.Num()-2; // Count deleted actors int32 NumDeletedActors = 0; for (int32 ActorIdx = 0; ActorIdx < Level->Actors.Num(); ++ActorIdx) { if (!Level->Actors[ActorIdx]) { ++NumDeletedActors; } } // Subtract deleted actors from the actor count LevelActorsCount -= NumDeletedActors; } UpdateDisplayName(); }
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; }
void FWorldTileModel::AddStreamingLevel(UClass* InStreamingClass, const FName& InPackageName) { if (LevelCollectionModel.IsReadOnly() || !IsEditable() || IsRootTile()) { return; } UWorld* LevelWorld = CastChecked<UWorld>(GetLevelObject()->GetOuter()); // check uniqueness if (LevelWorld->StreamingLevels.FindMatch(ULevelStreaming::FPackageNameMatcher(InPackageName)) != INDEX_NONE) { return; } ULevelStreaming* StreamingLevel = static_cast<ULevelStreaming*>(StaticConstructObject(InStreamingClass, LevelWorld, NAME_None, RF_NoFlags, NULL)); // Associate a package name. StreamingLevel->PackageName = InPackageName; // Seed the level's draw color. StreamingLevel->DrawColor = FColor::MakeRandomColor(); StreamingLevel->LevelTransform = FTransform::Identity; StreamingLevel->PackageNameToLoad = InPackageName; // Add the streaming level to level's world LevelWorld->StreamingLevels.Add(StreamingLevel); LevelWorld->GetOutermost()->MarkPackageDirty(); }
void FWorldTileModel::SetVisible(bool bVisibile) { if (LevelCollectionModel.IsReadOnly()) { return; } ULevel* Level = GetLevelObject(); if (Level == NULL) { return; } // Don't create unnecessary transactions if (IsVisible() == bVisibile) { return; } // Can not show level outside of editable area if (bVisibile && !ShouldBeVisible(LevelCollectionModel.EditableWorldArea())) { return; } // The level is no longer shelved bWasShelved = false; { FScopedTransaction Transaction( LOCTEXT("ToggleVisibility", "Toggle Level Visibility") ); // This call hides/shows all owned actors, etc EditorLevelUtils::SetLevelVisibility(Level, bVisibile, true); // Ensure operation is completed succesfully check(GetLevelObject()->bIsVisible == bVisibile); // Now there is no way to correctly undo level visibility // remove ability to undo this operation Transaction.Cancel(); } }
bool FLevelModel::IsLocked() const { ULevel* Level = GetLevelObject(); if (Level) { return FLevelUtils::IsLevelLocked(Level); } return false; }
void FWorldTileModel::EnsureLevelHasBoundsActor() { ULevel* Level = GetLevelObject(); if (Level && !Level->LevelBoundsActor.IsValid()) { FActorSpawnParameters SpawnParameters; SpawnParameters.OverrideLevel = Level; LevelCollectionModel.GetWorld()->SpawnActor<ALevelBounds>(SpawnParameters); } }
bool FLevelModel::IsVisible() const { if (LevelCollectionModel.IsSimulating()) { return SimulationStatus.bVisible; } else { ULevel* Level = GetLevelObject(); return Level ? FLevelUtils::IsLevelVisible(Level) : false; } }
void FWorldTileModel::OnAlwaysLoadedPropertyChanged() { if (GetLevelObject()) { SetAlwaysLoaded(TileDetails->bAlwaysLoaded); LevelCollectionModel.RequestUpdateAllLevels(); return; } // Restore original value FWorldTileInfo Info = LevelCollectionModel.GetWorld()->WorldComposition->GetTileInfo(TileDetails->PackageName); TileDetails->bAlwaysLoaded = Info.bAlwaysLoaded; }
void FLevelModel::SelectActors(bool bSelect, bool bNotify, bool bSelectEvenIfHidden, const TSharedPtr<ActorFilter>& Filter) { if (LevelCollectionModel.IsReadOnly()) { return; } ULevel* Level = GetLevelObject(); if (Level == NULL || IsLocked()) { return; } Editor->GetSelectedActors()->BeginBatchSelectOperation(); bool bChangesOccurred = false; // Iterate over all actors, looking for actors in this level. for (auto It = Level->Actors.CreateIterator(); It; ++It) { AActor* Actor = (*It); if (Actor) { if (Filter.IsValid() && !Filter->PassesFilter(Actor)) { continue; } //exclude the world settings and builder brush from actors selected const bool bIsWorldSettings = Actor->IsA(AWorldSettings::StaticClass()); const bool bIsBuilderBrush = (Actor->IsA(ABrush::StaticClass()) && FActorEditorUtils::IsABuilderBrush(Actor)); if (bIsWorldSettings || bIsBuilderBrush) { continue; } bool bNotifyForActor = false; Editor->GetSelectedActors()->Modify(); Editor->SelectActor(Actor, bSelect, bNotifyForActor, bSelectEvenIfHidden); bChangesOccurred = true; } } Editor->GetSelectedActors()->EndBatchSelectOperation(); if (bNotify) { Editor->NoteSelectionChange(); } }
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); } }
FString FLevelModel::GetFileSizeString() const { FString MemorySizeString; ULevel* Level = GetLevelObject(); //if (Level && GetDefault<ULevelBrowserSettings>()->bDisplayFileSize) //{ // // 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; }
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; }
FString FLevelModel::GetLightmassSizeString() const { FString MemorySizeString; ULevel* Level = GetLevelObject(); if (Level && Editor->AccessEditorUserSettings().bDisplayLightmassSizeInLevelBrowser) { // Update metrics static const float ByteConversion = 1.0f / 1024.0f; float LightmapSize = Level->LightmapTotalSize * ByteConversion; MemorySizeString += FString::Printf(TEXT( "%.2f" ), LightmapSize); } return MemorySizeString; }
FString FLevelModel::GetLightmassSizeString() const { FString MemorySizeString; ULevel* Level = GetLevelObject(); //if (Level && GetDefault<ULevelBrowserSettings>()->bDisplayLightmassSize) //{ // // Update metrics // static const float ByteConversion = 1.0f / 1024.0f; // float LightmapSize = Level->LightmapTotalSize * ByteConversion; // // MemorySizeString += FString::Printf(TEXT( "%.2f" ), LightmapSize); //} return MemorySizeString; }
void FLevelModel::SelectActors(bool bSelect, bool bNotify, bool bSelectEvenIfHidden, const TSharedPtr<ActorFilter>& Filter) { if (LevelCollectionModel.IsReadOnly()) { return; } ULevel* Level = GetLevelObject(); if (Level == NULL || IsLocked()) { return; } Editor->GetSelectedActors()->BeginBatchSelectOperation(); bool bChangesOccurred = false; // Iterate over all actors, looking for actors in this level. for (auto It = Level->Actors.CreateIterator(); It; ++It) { AActor* Actor = (*It); if (Actor) { if (Filter.IsValid() && !Filter->PassesFilter(Actor)) { continue; } bool bNotifyForActor = false; Editor->GetSelectedActors()->Modify(); Editor->SelectActor(Actor, bSelect, bNotifyForActor, bSelectEvenIfHidden); bChangesOccurred = true; } } Editor->GetSelectedActors()->EndBatchSelectOperation(); if (bNotify) { Editor->NoteSelectionChange(); } }
void FLevelModel::DeselectAllSurfaces() { ULevel* Level = GetLevelObject(); if (Level == NULL) { return; } UModel* Model = Level->Model; for (int32 SurfaceIndex = 0; SurfaceIndex < Model->Surfs.Num(); ++SurfaceIndex) { FBspSurf& Surf = Model->Surfs[SurfaceIndex]; if (Surf.PolyFlags & PF_Selected) { Model->ModifySurf(SurfaceIndex, false); Surf.PolyFlags&= ~PF_Selected; } } }
void FWorldTileModel::OnParentPackageNamePropertyChanged() { if (GetLevelObject() && !TileDetails->bAlwaysLoaded) { TSharedPtr<FLevelModel> NewParent = LevelCollectionModel.FindLevelModel(TileDetails->ParentPackageName); // Assign to a root level if new parent is not found if (!NewParent.IsValid()) { NewParent = static_cast<FWorldTileCollectionModel&>(LevelCollectionModel).GetWorldRootModel(); } FLevelModelList LevelList; LevelList.Add(this->AsShared()); LevelCollectionModel.AssignParent(LevelList, NewParent); return; } // Restore original parent FWorldTileInfo Info = LevelCollectionModel.GetWorld()->WorldComposition->GetTileInfo(TileDetails->PackageName); TileDetails->ParentPackageName = FName(*Info.ParentTilePackageName); }
void FWorldTileModel::OnPositionPropertyChanged() { FWorldTileInfo Info = LevelCollectionModel.GetWorld()->WorldComposition->GetTileInfo(TileDetails->PackageName); if (GetLevelObject()) { // Get the delta FIntPoint Delta = TileDetails->Position - Info.Position; // Snap the delta FLevelModelList LevelsList; LevelsList.Add(this->AsShared()); FVector2D SnappedDelta = LevelCollectionModel.SnapTranslationDelta(LevelsList, FVector2D(Delta), 0.f); // Set new level position SetLevelPosition(Info.AbsolutePosition + FIntPoint(SnappedDelta.X, SnappedDelta.Y)); return; } // Restore original value TileDetails->Position = Info.Position; }
void FLevelModel::DeselectAllActors() { ULevel* Level = GetLevelObject(); if (Level == NULL) { return; } USelection* SelectedActors = Editor->GetSelectedActors(); SelectedActors->Modify(); // Deselect all level actors for (auto It = Level->Actors.CreateIterator(); It; ++It) { AActor* CurActor = (*It); if (CurActor) { SelectedActors->Deselect(CurActor); } } }
void FStreamingLevelModel::UpdatePackageFileAvailability() { // Check if streaming level has a valid package name if (!GetLevelObject()) { if (LevelStreaming.IsValid()) { FString PackageName = LevelStreaming->PackageNameToLoad == NAME_None ? LevelStreaming->GetWorldAssetPackageName() : LevelStreaming->PackageNameToLoad.ToString(); bHasValidPackageName = FPackageName::DoesPackageExist(PackageName); } else { bHasValidPackageName = false; } } else { bHasValidPackageName = true; } }
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); } } }
void FLevelModel::SetLocked(bool bLocked) { if (LevelCollectionModel.IsReadOnly()) { return; } ULevel* Level = GetLevelObject(); if (Level == NULL) { return; } // Do nothing if attempting to set the level to the same locked state if (bLocked == IsLocked()) { return; } // If locking the level, deselect all of its actors and BSP surfaces if (bLocked) { DeselectAllActors(); DeselectAllSurfaces(); // Tell the editor selection status was changed. Editor->NoteSelectionChange(); // If locking the current level, reset the p-level as the current level //@todo: fix this! } // Change the level's locked status FLevelUtils::ToggleLevelLock(Level); }
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.") ); } }
bool FLevelModel::IsLoaded() const { return (LevelCollectionModel.IsSimulating() ? SimulationStatus.bLoaded : (GetLevelObject() != NULL)); }
bool FLevelModel::HasKismet() const { return (GetLevelObject() != NULL); }