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();
}