Delegate invocation list changes inside a constructor does not propagate to a derived blueprint.

Hello,

I know there are many questions that are very similar to mine and most of it concludes with a solution stating that the changes get through after a rebuild/restart of the editor. And some posts say that its a bug and have been reported.

But in my case I do not have any problem making changes to VARIABLES inside a constructor. Those changes get reflected in blueprint after a compile. But if make I changes to an invocation list of any delegate, the changes do not go through to the blueprint no matter how many times I rebuild/restart the editor.

For Example,


pawnSensor->OnSeePawn.AddDynamic(this, &AFPSAIGuard::OnPawnSeen);

If I add the above line to the constructor after I’ve derived a Blueprint based on this C++ class, there is no way that function gets registered in the Blueprint. I’ve to recreate the blueprint to get it to work.

I’m using UE 4.19.1. What am I doing wrong here? I recently started UE and any help is appreciated.

Thanks.

I’d advise never binding delegates from a UObject constructor, the serialization is bugged and when you do this on blueprint base classes and subsequently make changes to the constructor, the state of the delegate in the saved blueprint can get corrupted. Once that has happened, aside from doing some very low level hackery, your only choice is to recreate the blueprint. But first, remove any binding from your constructor and put them elsewhere, BeginPlay will generally be fine.

Hey kamrann,
Thanks for the answer. Yea I moved the delegate binding code to BeginPlay after I posted. I just wanted to understand why it wasnt working inside the constructor. I’m actually following an Epic Games approved tutorial and the delegate binding works for the tutor in UE 4.18. So I’m guessing something is broken in 4.19.1 which I’m using.

A lot of people do it that way, and it will mostly work. But it’s susceptible to serialization issues when combining C++ changes with derived blueprints. It just depends on which changes you make and when as to whether the issue will show up. It’s been that way as long as I’ve been using UE4, hence my recommendation.

Hey Kamrann,
Sorry for the delayed response. Thank you for taking the time to explain. Serialization issues I see. I’m getting more and more cozy with C++ each day. This advice really helped!

There is a solution actually, and it’s simply renaming the UPROPERTY pointer to the object/component you are binding to. I’ve also renamed the internal name of the object at the same time, but I don’t think that is necessary. After renaming, recompile and save all the BPs that derive from that actor, then rename it back (and optionally re-save the BPs again). It will now work. Though, given this problem, binding stuff in the constructor might not be the best idea, but it is tempting as you have access to the event in the editor previews and also just before begin play and stuff (plus you don’t really need to worry about end play or the actor being in a hidden level and receiving a temporary end play).

I also ran into this too.

Apparently the CDO can be bound to all instances of that class so you get some very strange results in multicast delegates if bound in the constructor.

I was incredibly confused debugging some code where some random instance of a class was being notified when I knew that shouldn’t be possible because there shouldn’t have been other instances. Turns out that instance was the CDO.

And this also doesn’t always happen. For example, if a subclass changes a default subobject class with ObjectInitializer.SetDefaultSubobjectClass it seemed to not keep the CDO saved in its multicast delegate invocation list.

So now I’m going to go through all of my code and scrub through to make sure I never assign delegates in constructors.