How to create a SphereComponent at runtime/dynamically?

I’m trying to create a SphereComponent dynamically 2 seconds after the level is started. For that I have this following code:

    void ACollidingPawnSpawnPawns::DelayedFunction() {
        // The first parameter 'SphereComponent' is the main component in the level and it has been created using the CreateDefaultSubobject method in the constructor of this class.  But that method can't be used outside the constructor.
        USphereComponent *dynamicallyCreatedSphere = NewObject<USphereComponent>(SphereComponent, USphereComponent::StaticClass());
            dynamicallyCreatedSphere ->InitSphereRadius(30.0f);
            dynamicallyCreatedSphere ->SetCollisionProfileName(TEXT("Pawn"));
            dynamicallyCreatedSphere ->SetRelativeLocation(FVector(155.0f, 165.0f, 45.0f));
            dynamicallyCreatedSphere ->SetVisibility(true);
}

After I run the level I don’t see this dynamic sphere pop up.

For the main ‘SphereComponent’ that does show up this code is in the constructor:

// Our root component will be a sphere that reacts to physics
SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("RootComponent"));
RootComponent = SphereComponent;
SphereComponent->InitSphereRadius(40.0f);
SphereComponent->SetCollisionProfileName(TEXT("Pawn"));

   // Create and position a mesh component so we can see where our sphere is
    UStaticMeshComponent* SphereVisual = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualRepresentation"));
    SphereVisual->SetupAttachment(RootComponent);
    static ConstructorHelpers::FObjectFinder<UStaticMesh> SphereVisualAsset(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere"));
    if (SphereVisualAsset.Succeeded())
    {
        SphereVisual->SetStaticMesh(SphereVisualAsset.Object);
        SphereVisual->SetRelativeLocation(FVector(0.0f, 0.0f, -40.0f));
        SphereVisual->SetWorldScale3D(FVector(0.8f));
    }

But again I can’t use the CreateDefaultSubobject to create the UStaticMeshComponent outside the constructor.

So I imagine for me to see my dynamicallyCreatedSphere in my level I would have to create a UStaticMeshComponentand I would need some variation of the FObjectFinder method to invoke (this FObjectFinder also doesn’t work outside the constructor).

I’ve been stuck on this for a while now. Anyone know how to do this?

Is it not created or do you simply not see it? AFAIC, such components by default are Visible, but HiddenInGame. What if instead of SetVisibility(true) you SetHiddenInGame(false)?

P.S. By the way, I remember trying to to spawn components at runtime like this, and it didn’t really work. Maybe try this instead:

USphereComponent *dynamicallyCreatedSphere = NewObject<USphereComponent>(this);

It seems to me that it isn’t created. Or as it could be as you say, it potentially is created but not visible.

I didn’t try the SetHiddenInGame(false) yet, but I finally was able to have the sphere dynamically created and visible.

Here’s the updates.

// In the .h file I have this

UPROPERTY(EditAnywhere)
UStaticMesh* StaticMesh;

USphereComponent* dynamicallyCreatedSphere = nullptr;
UStaticMeshComponent* dynamicMesh = nullptr;

// In the cpp file I have this outside the constructor

void ACollidingPawnSpawnPawns::spawnPawns()
{
    if (dynamicallyCreatedSphere == nullptr) {
        //dynamicallyCreatedSphere = NewObject<USphereComponent>(USphereComponent::StaticClass()); // compiles
        dynamicallyCreatedSphere = NewObject<USphereComponent>(SphereComponent, USphereComponent::StaticClass());
        //dynamicallyCreatedSphere->SetupAttachment(SphereComponent);
        dynamicallyCreatedSphere->InitSphereRadius(30.0f);
        dynamicallyCreatedSphere->SetCollisionProfileName(TEXT("Pawn"));
        dynamicallyCreatedSphere->SetRelativeLocation(FVector(155.0f, 165.0f, 45.0f));
        dynamicallyCreatedSphere->SetVisibility(true);


        dynamicMesh = NewObject<UStaticMeshComponent>(this);
        dynamicMesh->AttachToComponent(dynamicallyCreatedSphere, FAttachmentTransformRules::KeepWorldTransform);
        dynamicMesh->RegisterComponent();
        dynamicMesh->SetStaticMesh(StaticMesh);
    }
}

Having the StaticMesh class variable declared as a UProperty allows me to select the mesh manually from UnrealEngine’s interface.

Then when I run the level that StaticMesh is used as the mesh for my class variable dynamicMesh and the dynamic component (in this case a sphere) is created and visible.

1 Like

Need write RegisterComponent();
Imgur