Search code examples
c++unreal-engine5

How do i use parameters with constructors?


I am programming in ue5 and i was creating a spatial hash. i needed to have a declared cell size for the hash, and i decided to use the constructor

Here is a similar code

HSpatialHash.h

UCLASS()
class xxx_API UHSpatialHash final : public UObject
{
    GENERATED_BODY()
public:
    explicit UHSpatialHash(const float PCellSize) {CellSize = PCellSize;}
}

Error message:

error C:\Users\user\OneDrive\Documents\Unreal Projects\attrition\Source\project name\Private\HSpatialHash.h(18):
error C2338: static_assert failed: 'You have to define UHSpatialHash::UHSpatialHash() or UHSpatialHash::UHSpatialHash(const FObjectInitializer&). 
This is required by UObject system to work correctly.'

I tried to add the FObjectInitializer parameter, but it didn't work. I tried to put in in the cpp file, nothing, i don't know what to do. Can you help me?


Solution

  • If you inherit from UObject, you have to provide either a default constructor or the one with the FObjectInitializer parameter. You create the object using NewObject() which does some internal initialization logic for the object and you can't pass parameters to it.

    i decided to use the constructor

    Depending on what you want to do, you probably should change your decision.

    Do you need it to be a UObject with reflection and editor visibility? Because then, it would be easier to just add an "Initialize()" method with the parameters you wanted to have in the constructor and call it after creation, like so:

    UCLASS()
    class xxx_API UHSpatialHash final : public UObject
    {
        GENERATED_BODY()
    public:
        inline void Initialize(const float PCellSize) { CellSize = PCellSize; }
    }
    

    and for creation:

    UHSpatialHash* spatialHash = NewObject<UHSpatialHash>(this);
    spatialHash->Initialize(cellSize);
    

    If you only want it to be a simple class without reflection, you can just use a regular C++ class and use your custom constructor.


    Another option would be to use a USTRUCT() instead. It can't do as much as the UCLASS(), but since you do not intent to inherit from it, it may be enough. You can define a custom constructor and do not need to care for the FObjectInitializer parameter.