Modifying UShapeComponent in Construction Script

I want to be able to change the shape type of a UShapeComponent from the construction script.

This component (RoomCollisionAreaShape) acts as root component of my actor, and, upon changing an enum (ERoomShape) parameter in the editor, the shape should change between Sphere, Capsule and Box.

Unfortunately, the OnConstruction method has some issues

Header file

UENUM()

enum ERoomShape

{
   Box = 1,
   Sphere = 2,
   Capsule = 3
};

UCLASS()
class PROJECT_API ARoomBox : public AActor {
GENERATED_BODY()
private:
   UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
   UShapeComponent* RoomCollisionAreaShape;
   UPROPERTY(EditAnywhere)
   TEnumAsByte<ERoomShape> RoomShape = ERoomShape::Box;
public:
   ARoomBox();
protected:
   virtual void BeginPlay() override;
   virtual void OnConstruction (const FTransform& Transform) override;
};

CPP code

ARoomBox::ARoomBox()
{
	PrimaryActorTick.bCanEverTick = true;
	RoomCollisionAreaShape = CreateDefaultSubobject<UBoxComponent>(TEXT("Room Collision Box"));
	RootComponent = RoomCollisionAreaShape;
}

void ARoomBox::OnConstruction (const FTransform& Transform)
 {
	Super::OnConstruction(Transform);
	// Only proceed with construction routine if the ShapeType has been changed and if RoomCollisionAreaShape has been created
	if(!RoomCollisionAreaShape)
	{
		UE_LOG(LogTemp, Display, TEXT("Room Area Shape doesn't exist"));
		return;
	}
	if(RoomCollisionAreaShape->GetCollisionShape().ShapeType == RoomShape.GetValue())
	{
		UE_LOG(LogTemp, Display, TEXT("Room Area Shape is %d and matches RoomShape param %d"), RoomCollisionAreaShape->GetCollisionShape().ShapeType, RoomShape.GetValue());
		return;
	}
	switch(RoomShape)
	{
		case(ERoomShape::Box):
			RoomCollisionAreaShape = Cast<UBoxComponent>(NewObject<UBoxComponent>(this));
		break;
		case(ERoomShape::Sphere):
			RoomCollisionAreaShape = Cast<USphereComponent>(NewObject<USphereComponent>(this));
		break;
		case(ERoomShape::Capsule):
			RoomCollisionAreaShape = Cast<UCapsuleComponent>(NewObject<UCapsuleComponent>(this));
		break;
		default:
			UE_LOG(LogTemp, Warning, TEXT("No shape selected for Room %s. Defaulting to Box"),*RoomName);
			RoomShape = ERoomShape::Box;
			RoomCollisionAreaShape = Cast<UBoxComponent>(NewObject<UBoxComponent>(this));
		break;
	}
 }

Now my problem is, I don’t even reach the switch case: my Construction method alerts me that RoomCollisionAreaShape doesn’t exist (first if statement).

And yet in the editor, it pretty much exists alright:

I don’t know what I’m doing wrong here. The only thing that comes to mind is that blueprints don’t allow generic UShapeComponents to be added in viewport, only Box/Capsule/Sphere components…

Hi kn0bbulo,
Try putting a breakpoint on the CreateDefaultSubobject() in the constructor - you may find you need to move that over to the constructor that takes the “const FObjectInitializer& ObjectInitializer” parameter (ie ARoomBox::ARoomBox(const FObjectInitializer& ObjectInitializer)")