bool UClassThumbnailRenderer::CanVisualizeAsset(UObject* Object) { if (ThumbnailScene == nullptr) { ThumbnailScene = new FClassThumbnailScene(); } UClass* Class = Cast<UClass>(Object); // Only visualize actor based classes if (Class && Class->IsChildOf(AActor::StaticClass())) { // Try to find any visible primitive components in the class' CDO AActor* CDO = Class->GetDefaultObject<AActor>(); TInlineComponentArray<UActorComponent*> Components; CDO->GetComponents(Components); for (auto CompIt = Components.CreateConstIterator(); CompIt; ++CompIt) { if (ThumbnailScene->IsValidComponentForVisualization(*CompIt)) { return true; } } } return false; }
void FSCSEditorViewportClient::ProcessClick(class FSceneView& View, class HHitProxy* HitProxy, FKey Key, EInputEvent Event, uint32 HitX, uint32 HitY) { if(HitProxy) { if(HitProxy->IsA(HInstancedStaticMeshInstance::StaticGetType())) { HInstancedStaticMeshInstance* InstancedStaticMeshInstanceProxy = ( ( HInstancedStaticMeshInstance* )HitProxy ); TSharedPtr<ISCSEditorCustomization> Customization = BlueprintEditorPtr.Pin()->CustomizeSCSEditor(InstancedStaticMeshInstanceProxy->Component); if(Customization.IsValid() && Customization->HandleViewportClick(AsShared(), View, HitProxy, Key, Event, HitX, HitY)) { Invalidate(); } } else if(HitProxy->IsA(HActor::StaticGetType())) { HActor* ActorProxy = (HActor*)HitProxy; AActor* PreviewActor = GetPreviewActor(); if(ActorProxy && ActorProxy->Actor && ActorProxy->Actor == PreviewActor && ActorProxy->PrimComponent != NULL) { TInlineComponentArray<USceneComponent*> SceneComponents; ActorProxy->Actor->GetComponents(SceneComponents); for(auto CompIt = SceneComponents.CreateConstIterator(); CompIt; ++CompIt) { USceneComponent* CompInstance = *CompIt; TSharedPtr<ISCSEditorCustomization> Customization = BlueprintEditorPtr.Pin()->CustomizeSCSEditor(CompInstance); if (Customization.IsValid() && Customization->HandleViewportClick(AsShared(), View, HitProxy, Key, Event, HitX, HitY)) { break; } if (CompInstance == ActorProxy->PrimComponent) { const bool bIsCtrlKeyDown = Viewport->KeyState(EKeys::LeftControl) || Viewport->KeyState(EKeys::RightControl); if (BlueprintEditorPtr.IsValid()) { // Note: This will find and select any node associated with the component instance that's attached to the proxy (including visualizers) BlueprintEditorPtr.Pin()->FindAndSelectSCSEditorTreeNode(CompInstance, bIsCtrlKeyDown); } break; } } } Invalidate(); } // Pass to component vis manager //GUnrealEd->ComponentVisManager.HandleProxyForComponentVis(HitProxy); } }
void FSCSEditorViewportClient::RefreshPreviewBounds() { AActor* PreviewActor = GetPreviewActor(); if(PreviewActor) { // Compute actor bounds as the sum of its visible parts TInlineComponentArray<UPrimitiveComponent*> PrimitiveComponents; PreviewActor->GetComponents(PrimitiveComponents); PreviewActorBounds = FBoxSphereBounds(ForceInitToZero); for(auto CompIt = PrimitiveComponents.CreateConstIterator(); CompIt; ++CompIt) { // Aggregate primitive components that either have collision enabled or are otherwise visible components in-game UPrimitiveComponent* PrimComp = *CompIt; if(PrimComp->IsRegistered() && (!PrimComp->bHiddenInGame || PrimComp->IsCollisionEnabled()) && PrimComp->Bounds.SphereRadius < HALF_WORLD_MAX) { PreviewActorBounds = PreviewActorBounds + PrimComp->Bounds; } } } }
void USimpleConstructionScript::FixupRootNodeParentReferences() { // Get the BlueprintGeneratedClass that owns the SCS UClass* BPGeneratedClass = GetOwnerClass(); if(BPGeneratedClass == NULL) { UE_LOG(LogBlueprint, Warning, TEXT("USimpleConstructionScript::FixupRootNodeParentReferences() - owner class is NULL; skipping.")); // cannot do the rest of fixup without a BPGC return; } for (int32 NodeIndex=0; NodeIndex < RootNodes.Num(); ++NodeIndex) { // If this root node is parented to a native/inherited component template USCS_Node* RootNode = RootNodes[NodeIndex]; if(RootNode->ParentComponentOrVariableName != NAME_None) { bool bWasFound = false; // If the node is parented to a native component if(RootNode->bIsParentComponentNative) { // Get the Blueprint class default object AActor* CDO = Cast<AActor>(BPGeneratedClass->GetDefaultObject(false)); if(CDO != NULL) { // Look for the parent component in the CDO's components array TInlineComponentArray<UActorComponent*> Components; CDO->GetComponents(Components); for (auto CompIter = Components.CreateConstIterator(); CompIter && !bWasFound; ++CompIter) { UActorComponent* ComponentTemplate = *CompIter; bWasFound = ComponentTemplate->GetFName() == RootNode->ParentComponentOrVariableName; } } else { // SCS and BGClass depends on each other (while their construction). // Class is not ready, so one have to break the dependency circle. continue; } } // Otherwise the node is parented to an inherited SCS node from a parent Blueprint else { // Get the Blueprint hierarchy TArray<const UBlueprintGeneratedClass*> ParentBPClassStack; const bool bErrorFree = UBlueprintGeneratedClass::GetGeneratedClassesHierarchy(BPGeneratedClass, ParentBPClassStack); // Find the parent Blueprint in the hierarchy for(int32 StackIndex = ParentBPClassStack.Num() - 1; StackIndex > 0; --StackIndex) { const UBlueprintGeneratedClass* ParentClass = ParentBPClassStack[StackIndex]; if( ParentClass != NULL && ParentClass->SimpleConstructionScript != NULL && ParentClass->GetFName() == RootNode->ParentComponentOwnerClassName) { // Attempt to locate a match by searching all the nodes that belong to the parent Blueprint's SCS for (USCS_Node* ParentNode : ParentClass->SimpleConstructionScript->GetAllNodes()) { if (ParentNode != nullptr && ParentNode->VariableName == RootNode->ParentComponentOrVariableName) { bWasFound = true; break; } } // We found a match; no need to continue searching the hierarchy break; } } } // Clear parent info if we couldn't find the parent component instance if(!bWasFound) { UE_LOG(LogBlueprint, Warning, TEXT("USimpleConstructionScript::FixupRootNodeParentReferences() - Couldn't find %s parent component '%s' for '%s' in BlueprintGeneratedClass '%s' (it may have been removed)"), RootNode->bIsParentComponentNative ? TEXT("native") : TEXT("inherited"), *RootNode->ParentComponentOrVariableName.ToString(), *RootNode->GetVariableName().ToString(), *BPGeneratedClass->GetName()); RootNode->bIsParentComponentNative = false; RootNode->ParentComponentOrVariableName = NAME_None; RootNode->ParentComponentOwnerClassName = NAME_None; } } } // call this after we do the above ParentComponentOrVariableName fixup, // because this operates differently for root nodes that have their // ParentComponentOrVariableName field cleared // // repairs invalid scene hierarchies (like when this Blueprint has been // reparented and there is no longer an inherited scene root... meaning one // of the scene component nodes here needs to be promoted) FixupSceneNodeHierarchy(); }