Search code examples
c++propertiesmacrosunreal-engine4

How to add UPROPERTY() macro within a c++ Macro


I want to have items created using c++ macros like this:

#define PROPERTIES\
UPROPERTY(blabla)\
variableType varName;\
UPROPERTY(blabla)\
variableType2 varName2;

So I can add properties to other files including this and using PROPERTIES macro on them.

class XYZ...
{

...

public:
      PROPERTIES

      ...
      UPROPERTY()
      varibleType3 name3;
      ....
}

This design comes from a typical organization, where those parameters come from another class because they are related to that class.

So I could include diferent files, and include all properties to show in the editor from all of them.

What's happening is that the Unreal Header Tool completely ignores UPROPERTY, of course, probably because it's being processed before and then the Macro... surprisingly is working but only the variable, not UPROPERTY... So the editor doesn't show it.

Any ideas on how to do this?


Solution

  • Are you sure that your properties are defined correctly? You should use something like UPROPERTY(EditAnywhere, Category="My category") Category is required when exposing Functions or Properties to editor. Properties with this macro would be exposed to instance properties editor and to class defaults editor as well.

    Also I'd like to point out, that this design is really poor and I think that you may have problems with it. As you correctly pointed out, Epic has custom reflection system (UHT)which allows you to use automatic memory management with GC and so on. More on Build System UE Docs.

    I think that you should decide how those properties will be used. Since you want to distribute them over multiple actors, you can choose from:

    1. Inheritance
    2. UObject reference
    3. Component system

    The first is really trivial and I believe you are familiar with this concept. And I think that you had your reasons why chose that macro solution. Note that you aren't allowed to use multiple inheritance (which is possible in classic C++) and this is due to UBT.

    The second one goes like this:

    UCLASS(BlueprintType)
    class UMyProps : public UObject
    {
         // TODO define properties in a standard way
    }
    
    // some actor's properties
    UPROPERTY(BlueprintReadWrite, Category = "My Game | My Subcategory")
    UMyProps* myProperties;
    

    Main advantage of the second system is that you can add sets of properties to objects that requires them while having type-safe environment and full Intellisence support (and UE Editor as well of course).

    Or you can use Components, which is more or less like the second approach, but it could be totally dynamic (you don't need actual reference to your component, you can get it by calling GetComponent(...)).

    These three are good, solid and transparent approaches to extend your object's properties. By using your macro's approach, you could easily ends up with a mountain of a mess, if this even works with UE build system).