4.7 How do I actually pass parameter's in the new constructor format?

Hey,

I have read up on 4.7’s new constructor using FObjectInitializer instead of the PCIP. This works great, and I can define a constructor without any parameters, or with the FObjectInitializer reference. Now, don’t understand how I can actually pass parameters through this constructor. My code looks like this:

.h



class APuzzleBlankBlockGrid : public AActor
{
	GENERATED_BODY()

	APuzzleBlankBlockGrid(const class FObjectInitializer& PCIP);


and .cpp




APuzzleBlankBlockGrid::APuzzleBlankBlockGrid(const class FObjectInitializer& PCIP)
	: Super(PCIP)
{


I can not really figure out where I pass any parameters in this constructor.
Thx in advance.

— RESOLVED —

User kamrann explained:

I might be wrong but im pretty sure constructor overloading is not possible. Ive been searching about it and AActor doesn’t support it, it may be possible for UObject but i couldn’t make it work.

1 Like

You should never actually directly call a constructor for a UObject anyway, so there is no way to pass in arguments. Just add an initialization method taking arguments if you need it.

1 Like

So I define a init() and call it right after spawning? I have very little experience in C++, and in other languages that seems like bad style, but it should work. Is this how Actors officially get their init values?

An init method seems fine. The “problem” here is that UE C++ practices deviate quite a bit from standard raw C++. As mentioned before, you never call the constructor directly, but that is not the only reason why you should keep the constructor as static as possible. UE creates default objects for each class, which run the constructor and basic initialization and you can access them at any point in the engine to read default values of a class.

DamageTypes are a good example: Say you create a derived blueprint class of a custom C++ DamageType class. In that blueprint asset you can now override default values, i.e. a flag for a poison debuff. Now when UE creates this class’ default object at runtime it will call the constructor and afterwards initialize the overriden properties. This is also why UE will complain if you change the name of UProperties, it can no longer assign values correctly. (The same system is used if you place actors in a level and change their values)

As far as I know the default object is also used for faster runtime construction of new objects by using them as a template.

When you spawn an actor, then UE will run a bunch of other methods on it before spawn returns (i.e. PostInitalizeComponents / BeginPlay). If you really need to set data before that you can use SpawnActorDeferred which will only do the most rudimentary initialization. You can then configure the object and use FinishSpawningActor to run the rest of the cycle.

greetings,
FTC

When you look at the Actor Class there is a function called AActor::InitializeDefaults(). This function is called within the constructor.

I honestly can’t find that function in the API, but there’s AActor::PostSpawnInitialize() which basically work that way… But I can only specify default values here, in order to pass parameters to this function, it doesn’t really help me, or am I missing something?

No you are correct. The UObject initialization method allows you to in a sense define various compile time parameters by simply modifying defaults, which will be automatically assigned to the object within its construction. However, in the case you need to pass runtime parameters from the call site (the code which is calling NewObject/SpawnActor), then the only approach is with some kind of Init method called afterwards.

You are also correct in that in C++ too, this is considered bad practice. However, currently at least, it is unavoidable with the UE4 reflection system. It seems feasible to me that they could possibly add variadic template versions of NewObject/SpawnActor, which would allow us to define constructors with parameters, but I’m not certain.

1 Like

Thanks! This is basically what I needed to hear. Cheers.