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…