Download

I need clarification on delegates in subobjects please

Hi all,

i have a weird problem with ue4 at the moment.
I have a ActorComponent for my character’s stats (UGameStatComponent) which should hold my char’s stats and also should send events when they are changed (for UI update etc).
Because i want to make it easily extendable i create the stats on the fly in the constructor like this:


    for (TObjectIterator<UClass> It; It; ++It)
    {
        if (It->IsChildOf(UEditableGameStat::StaticClass()) && !It->HasAnyClassFlags(CLASS_Abstract) && (*It != UEditableGameStat::StaticClass()))
        {
            UGameStatBase* newObject = (UGameStatBase*)objectInitializer.CreateDefaultSubobject(this, It->GetFName(), *It, *It, true, false, false);
            newObject->ThisGameStatChangedDelegate.AddDynamic(this, &UGameStatsComponent::SomeStatChanged);
            newObject->Owner = this;
            AllStats.Add(newObject);
        }
    }

So far so good.
My stats classes also have a dynamic multicast delegate which fires on change of the value. Works as intended from BP.

But now it gets weird:
I also want to have a general event if any stat changes, so i thought, i just set another delegate from each stat to my UGameStatsComponent and fire both events. But whatever i do, the ThisGameStatChangedDelegate event never gets called. The code where it would do the broadcast is called, it’s just that the delegate’s array is empty.

So i did some digging and debugging. What i could find out is that the events are cleared away sometime between PostInitProperties and the actual gameplay. (They are definitively set/added)
I could not find out why or where this happens (even tried with break on value in VS, no luck).

So i really would appreciate some clarification or howto from a dev on how and when to set delegates in subobjects, because they just don’t seem to stick.

PS: I also tried it with a TWeakObjectPtr as means to callback directly, no luck either. Even though it is set in Constructor or PostInitProperties or PostLoad, when it is needed, then it’s just a nullptr.

Here is my class layout:



UGameStatBase
--> UEditableGameStat
      --> UGSStrength
      --> UGSDexterity etc.

UGameStatsComponent
(Creates an array of all childclasses of UGameStatBase and stores them in an internal array to be accessed a enum-index-system)


Thx in advance