void FSCSEditorViewportClient::Tick(float DeltaSeconds) { FEditorViewportClient::Tick(DeltaSeconds); // Register the selection override delegate for the preview actor's components TSharedPtr<SSCSEditor> SCSEditor = BlueprintEditorPtr.Pin()->GetSCSEditor(); AActor* PreviewActor = GetPreviewActor(); if (PreviewActor != nullptr) { TInlineComponentArray<UPrimitiveComponent*> PrimitiveComponents; PreviewActor->GetComponents(PrimitiveComponents); for (int32 CompIdx = 0; CompIdx < PrimitiveComponents.Num(); ++CompIdx) { UPrimitiveComponent* PrimComponent = PrimitiveComponents[CompIdx]; if (!PrimComponent->SelectionOverrideDelegate.IsBound()) { SCSEditor->SetSelectionOverride(PrimComponent); } } } else { InvalidatePreview(false); } if ( PreviewActor != LastPreviewActor.Get() || PreviewActor == nullptr || IsRealtime() ) { LastPreviewActor = PreviewActor; Invalidate(); RefreshPreviewBounds(); } // Tick the preview scene world. if (!GIntraFrameDebuggingGameThread) { // Ensure that the preview actor instance is up-to-date for component editing (e.g. after compiling the Blueprint, the actor may be reinstanced outside of this class) if(PreviewActor != BlueprintEditorPtr.Pin()->GetBlueprintObj()->SimpleConstructionScript->GetComponentEditorActorInstance()) { BlueprintEditorPtr.Pin()->GetBlueprintObj()->SimpleConstructionScript->SetComponentEditorActorInstance(PreviewActor); } // Allow full tick only if preview simulation is enabled and we're not currently in an active SIE or PIE session if(bIsSimulateEnabled && GEditor->PlayWorld == NULL && !GEditor->bIsSimulatingInEditor) { PreviewScene->GetWorld()->Tick(IsRealtime() ? LEVELTICK_All : LEVELTICK_TimeOnly, DeltaSeconds); } else { PreviewScene->GetWorld()->Tick(IsRealtime() ? LEVELTICK_ViewportsOnly : LEVELTICK_TimeOnly, DeltaSeconds); } } }
void FSCSEditorViewportClient::UpdatePreviewActorForBlueprint(UBlueprint* InBlueprint, bool bInForceFullUpdate/* = false*/) { AActor* PreviewActor = GetPreviewActor(); // Signal that we're going to be constructing editor components if(InBlueprint != NULL && InBlueprint->SimpleConstructionScript != NULL) { InBlueprint->SimpleConstructionScript->BeginEditorComponentConstruction(); } // If the Blueprint is changing if(InBlueprint != PreviewBlueprint || bInForceFullUpdate) { // Destroy the previous actor instance DestroyPreview(); // Save the Blueprint we're creating a preview for PreviewBlueprint = InBlueprint; // Spawn a new preview actor based on the Blueprint's generated class if it's Actor-based if(PreviewBlueprint && PreviewBlueprint->GeneratedClass && PreviewBlueprint->GeneratedClass->IsChildOf(AActor::StaticClass())) { FVector SpawnLocation = FVector::ZeroVector; FRotator SpawnRotation = FRotator::ZeroRotator; // Spawn an Actor based on the Blueprint's generated class FActorSpawnParameters SpawnInfo; SpawnInfo.bNoCollisionFail = true; SpawnInfo.bNoFail = true; SpawnInfo.ObjectFlags = RF_Transient; // Temporarily remove the deprecated flag so we can respawn the Blueprint in the viewport bool bIsClassDeprecated = PreviewBlueprint->GeneratedClass->HasAnyClassFlags(CLASS_Deprecated); PreviewBlueprint->GeneratedClass->ClassFlags &= ~CLASS_Deprecated; PreviewActorPtr = PreviewActor = PreviewScene->GetWorld()->SpawnActor( PreviewBlueprint->GeneratedClass, &SpawnLocation, &SpawnRotation, SpawnInfo ); // Reassign the deprecated flag if it was previously assigned if(bIsClassDeprecated) { PreviewBlueprint->GeneratedClass->ClassFlags |= CLASS_Deprecated; } check(PreviewActor); // Ensure that the actor is visible if(PreviewActor->bHidden) { PreviewActor->bHidden = false; PreviewActor->MarkComponentsRenderStateDirty(); GetWorld()->SendAllEndOfFrameUpdates(); } // Prevent any audio from playing as a result of spawning if(GEngine->AudioDevice) { GEngine->AudioDevice->Flush(GetWorld()); } // Set the reference to the preview actor for component editing purposes if(PreviewBlueprint->SimpleConstructionScript != NULL) { PreviewBlueprint->SimpleConstructionScript->SetComponentEditorActorInstance(PreviewActor); } // Run the construction scripts again, otherwise the actor will appear as though it's had a script pass first, rather than the default properties as shown in the details panel PreviewActor->RerunConstructionScripts(); } } else if(PreviewActor) { PreviewActor->RerunConstructionScripts(); } // Signal that we're done constructing editor components if(InBlueprint != NULL && InBlueprint->SimpleConstructionScript != NULL) { InBlueprint->SimpleConstructionScript->EndEditorComponentConstruction(); } Invalidate(); RefreshPreviewBounds(); }