Actor.GetComponents() returns Null for blueprint generated actor

I have an Actor Factory that is built using both C++ and BluePrint.
This factory spawns actors using Blueprint with the “Spawn Actor From Class” Node. If the actor class chosen in this node is “Static Mesh Actor” then in my C++ code: Actor.GetComponents(comp) returns correctly all the static mesh components of the actor.
However, if the class is a BluePrint Generated Class (a blueprint I made) which creates static mesh instances (root component is a Spline and attached to it are instanced static mesh components that I am interested in), then GetComponents returns Null. Even if I try Actor.GetComponents to get all actor components, or Actor.GetComponents to get all instanced static mesh components it still returns Null.
How do I get all instanced static mesh components when spawning an actor using a blueprint ? And how is it different than just using a static mesh actor ?

Oops, the angle brackets were removed from the above description. I use “UStaticMeshComponent” or “UInstancedStaticMeshComponent” or “UActorComponent” in angle brackets when calling GetComponents.

Can you paste code of your search loop? (assuming you have one as you using GetComponents)

This is the loop:

void Tag(const AActor &Actor)
{
  TArray<UStaticMeshComponent *> StaticMeshComponents;
  Actor.GetComponents<UStaticMeshComponent>(StaticMeshComponents);
  for (UStaticMeshComponent *Component : StaticMeshComponents) {
       UE_LOG(MyLog, Log, TEXT("Static Mesh Component found"));
 }

I found this post: https://answers.unrealengine.com/questions/372457/how-to-get-a-component-in-c-that-was-added-in-blue.html with a similar issued. This code is executed at spawning of the actor (blueprint generated actor). Is it possible that the instanced static meshes are not yet created at spawn time? and that they only exist after BeginPlay() is executed ? (As opposed to an actor that spawns static mesh actors and not instanced static meshes - in which case, the code works just fine!!)

Look ok to me, when do you call it in both cases (when it works and when it’s not)? Since this will give you multiple results if you have more static mesh components how do you do picking?

Ok i found you other comment land to moderation. All component should exist regardless of there state on begin play, or else you create them dynamically on other point then constructor or blueprint declared components.

The call in both cases is exactly the same. There is a delegate defined via : FOnActorSpawned::FDelegate::CreateUObject(this, &UTaggerDelegate::OnActorSpawned). To the best of my understanding, when the object is created the OnActorSpawend method is called and it calls the Tag function I posted earlier.

  • Don’t worry about selecting the component, this is just simplified code.

Hello,

I don’t expect to have made it in time, but I want to leave this here for everyone who is having this exact problem (like you and me).

The solution is to access the Construction script of the blueprint, there you get the USCSNodes - the complete component hierarchy as a list, if you want - and then you convert those nodes to USceneComponents.

I do this with those two methods:

TArray<USCS_Node*> USOLIDBPFunctionLibrary::GetAllBlueprintNodes(UBlueprint* Blueprint)
{
    TArray<USCS_Node*> uscsNodes;
    if (Blueprint != NULL)
    {
        uscsNodes = Blueprint->SimpleConstructionScript->GetAllNodes();
    }
    return uscsNodes;
}

To convert the nodes individually you can use this function:

USceneComponent* SOLIDBPFunctionLibrary::GetComponentFromNode(USCS_Node* Node)
{
    if (Node != NULL)
    {
        return Cast<USceneComponent>(Node->ComponentTemplate);
    }
    return nullptr;
}

But for sure it would be cooler if “GetAllComponents” would actually work on the received CDO of a blueprint, which still does not.

Kind regards,

Mirko

2 Likes