Download

Why does my Actor need a different constructor than the wizard created ones?

So this is confusing me.

If I create a new custom Actor by using the wizard in the editor, the stub code it generates uses a simple AMyActor::AMyActor() constructor.

However since I am making a plugin, I have to add code by hand as the wizard can’t add to that. So I created my custom actor by hand, reference code here and there to figure out what I needed. The odd thing though is that my actor inside the plugin requires a completely different constructor in order to link, and I don’t get why? In both cases they directly inherit from AActor so why would they be different?

In the plugin it has to be AMyActor::AMyActor(const FObjectInitializer& ObjectInitializer)

I am a beginner but from what I understand, using (const FObjectInitializer& ObjectInitializer) as a constructor argument allows for garbage collection by the engine. In other words, the engine will not be aware of the class unless you add that line. Keep in mind I am far from knowledgeable on the subject.

I know that AActor has both a argumentless constructor and one that takes an ObjectInitializer. I don’t know why when making a plugin, you can’t get the argumentless constructor to work if it did work outside of a plugin environment. Are you sure the plugin environment is the only difference?

I know that if you inherit from any subclass of actor that only has a constructor with ObjectInitializer (for example you inherit from ACharacter), your class must also have that constructor. Another thing I can think of is that your class requires a constructor with ObjectInitializer the moment that you have properties that are modifiable in blueprint for example. Because the ObjectInitializer is required for that:

Source: https://docs.unrealengine.com/latest/INT/Programming/UnrealArchitecture/Reference/Classes/index.html

The replacement for [FONT=Lucida Console]ObjectInitializer.CreateDefaultSubobject (probably the most used method of FObjectInitializer) is now the method [FONT=Lucida Console]CreateDefaultSubobject inside the UObject class. This method gets a pointer to the FObjectInitializer from a stack-like structure automatically. As far as I know the explicit way using FObjectInitializer in the constructor is the old way of creating subobjects while the new one is just calling [FONT=Lucida Console]CreateDefaultSubobject. So you don’t need the FObjectInitializer for blueprint types anymore.

Otherwise it could be some preprocessing magic going on here. What linker errors do you get exactly?

Can you check does the wizard use GENERATED_UCLASS_BODY or GENERATED_BODY? I think GENERATED_UCLASS_BODY generates a constructor signature with the FObjectInitializer.

You are a genius. Yes indeed I see that now. One generated from the wizard does indeed use the simpler GENERATED_BODY and I am using GENERETED_UCLASS_BODY. Very interesting.

Basically, GENERATED_BODY is newer and the one people should really use. It allows you to have Parameter-less constructors, and by default the Wizard uses that because it doesn’t know if you will or won’t specify any sub-objects or components on the Actor or Object. Using GENERATED_BODY also requires that you actually declare the constructor in the Header file, (with or without params).

The old GENERATED_UCLASS_BODY doesn’t allow Parameter-less Constructors, and also doesn’t require you to define the constructors either, it’s done in the Generated header file.