Ue5 in C++, How to Create a Component Based on Two (Or More) Components?

I first have to say that I'm new to Unreal :/

What I would like is two classes : One would be a component (CubeBlockComponent) which would be a CollisionBox with a Mesh, so I would like to use a UBoxComponent and a UStaticMeshComponent. Second would be an Actor (ModuleActor) combining several CubeBlockComponent.

I was able to get the desired behavior with an actor composed of several BoxComponent and StaticMeshComponent, but configurating them the same way each time I want to add one block is a pain, thus the need of a CubeBlockComponent.

My problem is I can't figure out how to do it properly. What should I do ?

I tried creating a c++ class (CubeBlockComponent) inherited from USceneComponent. I added a UStaticMeshComponent and a UBoxComponent :

    UPROPERTY(EditAnywhere, BlueprintReadWrite)
        UStaticMeshComponent* cubeStaticMesh;
    UPROPERTY(EditAnywhere)
        UBoxComponent* boxCollision;

And created them with CreateDefaultSubobject in the constructor:

    // Create box collision
    boxCollision = CreateDefaultSubobject<UBoxComponent>(TEXT("BoxCollision"));
    boxCollision->SetBoxExtent(FVector(40.f, 40.f, 40.f));
    boxCollision->SetupAttachment(this);

    // Create Cube static mesh
    cubeStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("CubeStaticMesh"));
    cubeStaticMesh->SetupAttachment(boxCollision);

Then, back in UE5 editor, I can make a blueprint component (BpCubeBlockComponent) based on my class (CubeBlockComponent). But this is bad as in BpCubeBlockComponent I can only modify cubeStaticMesh and boxCollision via "Open selecttion in Propery Matrix". And also, when I combine several BpCubeBlockComponent in an actor, the meshes just stays at the origin.

I feel like I should just create a class inheriting UBoxComponent, and basically recreating all UStaticMeshComponent functionalities inside the class, which would be a pain...

1 Answer

After hours of testing I found a solutions which I found quite good.

First, one should know that adding a component from another component is not recommended ; I guess it does not go well with Actor/component principle.

That said I was able to do it by overloading the OnRegister() method. So once a component is registered, it can attach other component to itself.

This is how it looks :

// CubeBlockComponent.h
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent), Blueprintable )
class BASIC2D_API UCubeBlockComponent : public UBoxComponent
{
    GENERATED_BODY()

public: 
    // Sets default values for this component's properties
    UCubeBlockComponent();

protected:
    // Called when the game starts
    virtual void BeginPlay() override;

public: 
    // Called every frame
    virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
    // Needed to attach other component
    virtual void OnRegister() override;

protected:
    UPROPERTY(EditAnywhere, BlueprintReadWrite)
        UStaticMeshComponent* cubeStaticMesh;
};

And

CubeBlockComponent.cpp
#include "CubeBlockComponent.h"

// Sets default values for this component's properties
UCubeBlockComponent::UCubeBlockComponent()
{
    // Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
    // off to improve performance if you don't need them.
    PrimaryComponentTick.bCanEverTick = true;

    // Create Cube static mesh, wait OnRegister to attach
    cubeStaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("CubeStaticMesh"));
}

// Called when the game starts
void UCubeBlockComponent::BeginPlay()
{
    Super::BeginPlay();
}
// Called every frame
void UCubeBlockComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}

void UCubeBlockComponent::OnRegister()
{
    Super::OnRegister();
    cubeStaticMesh->SetupAttachment(this);
}
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Elena Rostova

Elena Rostova

Lead Health, Wellness & Medical Journalist

Elena Rostova holds a Master's degree in Public Health Journalism. She covers groundbreaking medical research, holistic wellness trends, mental health awareness, and nutritional science.

Share this article
Twitter Facebook Pinterest