Spawning components dynamically - illegal use of this type as expression error

I’m trying to dynamically spawn components to a Pawn but I’m receiving an “illegal use of this type as expression error” error while doing so.

Being new to CPP I’m not entirely sure what’s wrong.

Within .cpp file.

    void AMyPawn::BeginPlay()
    {
    	CreateShapes();
    	Super::BeginPlay();
    	
    }
    
    void AMyPawn::CreateShapes()
    {
    	MakeComponent(USphereComponent, GetActorLocation(), GetActorRotation(), FName(TEXT("Sphere1")));
    	MakeComponent(UArrowComponent, GetActorLocation(), GetActorRotation(), FName(TEXT("Arrow1")));
    }
    
    void AMyPawn::MakeComponent(UClass* compClass, const FVector& relativeLocation, const FRotator& relativeRotation, FName& visualName)
    {
    	USceneComponent* createdComp = ConstructObject<USceneComponent>(compClass, this, visualName);
    	if (createdComp)
    	{
    		createdComp->RegisterComponent();
    		createdComp->AttachTo(GetRootComponent(), NAME_None);
    		createdComp->SetRelativeLocation(relativeLocation);
    		createdComp->SetRelativeRotation(relativeRotation);
    
    	}
    }

These lines error on the first argument

    	MakeComponent(USphereComponent, GetActorLocation(), GetActorRotation(), FName(TEXT("Sphere1")));
    	MakeComponent(UArrowComponent, GetActorLocation(), GetActorRotation(), FName(TEXT("Arrow1")));

The .h file under Public

	void CreateShapes();
	void MakeComponent(UClass* compClass, const FVector& location, const FRotator& rotation, FName& visualName);

You need to pass in USphereComponent::StaticClass() to obtain the UClass* that your code needs. Simply using the class name does not result in meaningful syntax.

In other words, you need to change this:

MakeComponent(USphereComponent, GetActorLocation(), GetActorRotation(), FName(TEXT("Sphere1")));
MakeComponent(UArrowComponent, GetActorLocation(), GetActorRotation(), FName(TEXT("Arrow1")));

into this:

MakeComponent(USphereComponent::StaticClass(), GetActorLocation(), GetActorRotation(), FName(TEXT("Sphere1")));
MakeComponent(UArrowComponent::StaticClass(), GetActorLocation(), GetActorRotation(), FName(TEXT("Arrow1")));

HTH.

Did some reading as to why that works. Is UArrowComponent the namespace and StaticClass a method in it?

Also, the components don’t seem to appear when I place the actor and run but I’ll worry about that later.

Yes that’s right, this has more to do with Unreal’s reflection system and the semantics surrounding that than being a regular C++ thing. In Unreal StaticClass() is a static function available for any UObject derived type and it returns a pointer to an appropriate UClass object.

UClass is a special metadata type that provides information about the C++ class from which an object was created. This is powerful because the UClass can be used and queried at runtime thus allowing for reflection (which is pretty much the backbone of many of Unreal’s editor and other systems).

Going back to your example, the function expects a UClass* parameter meaning passing just the literal class name “USphereComponent” as you did results in a compilation error (because the compiler looks for an actual pointer to a UClass object) and hence the “illegal use of this type as expression” error.

Further reading: Unreal Property System (Reflection) - Unreal Engine