[Request] UPROPERTY() Trackable (or something to track property value changes)

So I recently run into this:

https://rocket.unrealengine.com/questions/14036/tracking-variable-changes-between-multiple-objects.html#answer-14052

I managed to solve it. But I think there can be a better solution, and I found this:

http://blogs.msdn.com/b/gpalem/archive/2008/06/19/tracking-c-variable-state-changes.aspx

It would nice to have such system directly in Unreal. It doesn’t even need to track custom types.
It would nice if we could mark property as trackable even only for primitive types (like int, float etc). So engine would check every 1s, every frame or every custom amount of time (set in config file, or maybe directly in UPROPERTY()), if the tracked property changed.
If it did, it would fire event that will notify that property has changed.

Event would need to be binded to said variable, so won’t it won’t trigger if any marked property changes (;.

EDIT:
Just to be clear the issue from first link, as it happens was invented on my own, and I over thanked it, as the solution was actually very simple.

But despite that it still would be able to track specified variables on global level and launch events when they are modified.
It still can be helpful, for intrducing special effects that will trigger only when certain variable was chaged.

Hi Lukasz,

I’m curious, where do you imagine handling these events? Would it be in code or a blueprint? Do you want this option for all UPROPERTY() items? Or would it suffice to just be able to “watch” blueprint variables?

Something like this is probably not viable for performance reasons (UProperties are changing a lot), but I am wondering if you have a specific use case in mind that could maybe be solved another way?

You could always make the properties private and access them through Getter/Setter methods. The setter function could in turn call a delegate notifying those who care. Does this sound like it might solve your needs?

I mainly thought about it for blueprints, and only for primitive types.

I actually solved my main issue (at least partially) by writing setters, getters and blank event methods.
When setter is triggered, it activate event method (which doesn’t have any code it is just empty void function), which in turn send notification to blueprint which have have this event and blueprint do something.

I haven’t yet tested on mass scale with multiple pawns triggering events, but in my limited tests it’s working.

I haven’t tried delegates for it. To be honest I don’t really know how to use them in communication between blueprints and code. But they might prove to be better solution that mine.

My main use case for such system, was in creating spells. For example we have spell which will trigger only if one variable will reach certain value.For example if health will reach 50% of current value it will trigger super-power.
Thing that is needed here is for the spell in question to keep track of health value in real-time.
It probably could be achieved using delegates, as the only thing that is needed here is to trigger spell when health reaches certain threshold.

This could be used for other things. Like trigger spawn of actor, when one variable will reach certain value (ie, troll will spawn only between 2am and 4am of game time).

I guess I probably over think the issue.

Delegates can show up as event dispatchers in your blueprint. As an example, you can look at how OnTakeAnyDamage is exposed in Actor.h.

You can create your own delegate property (let’s call it OnHealthUpdated), then invoke it in your setter with OnHealthUpdated.Broadcast(). If it’s exposed to your blueprint (via the “BlueprintAssignable” tag), you can then create an OnHealthUpdated_Event node from the event dispatcher and handle it that way.

Your way works fine, but this might clean up that empty function for you.

Thanks for tip. I haven’t realized it, but that means I can decaler custom delegate using:

DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams 

And other macros ?

Yeah, you use those macro to define the delegate type. They’re used to define the delegate’s signature (parameters, return type, etc.). It’s kind of like typedefing a function pointer.

Then you take the defined type and use it like to declare properties (like OnTakeAnyDamage).

Hm it seems it doesn’t work. I setup simple code, to check how it is going to work and it seems like the event is not broadcasted to blueprint.

DECLARE_DYNAMIC_MULTICAST_DELEGATE( FCharacterHealthChange);

UPROPERTY(BlueprintAssignable)
FCharacterHealthChange OnCharacterHealthChange;

An in implementation:

void ARPGCharacter::ModifyAtrribute(FCharacterAttributes modAttri, bool damage)
{
	if(damage)
	{
		Attributes.Health = Attributes.Health - modAttri.Health;
		Attributes.Endurance = Attributes.Endurance - modAttri.Endurance;
		Attributes.Energy = Attributes.Energy - modAttri.Energy;
	}
	else
	{
		Attributes.Health = Attributes.Health + modAttri.Health;
		Attributes.Endurance = Attributes.Endurance + modAttri.Endurance;
		Attributes.Energy = Attributes.Energy + modAttri.Energy;
	}
	OnCharacterHealthChange.Broadcast();
}

And here simple blueprint:

Just to be clear

OnCharacterHealthChange.Broadcast();

Is triggered, as far as I can tell while debugging breakpoints.

Maybe the issue is that the delegate is not bound ? But if so how do I bind delegate that do not need to trigger any functions ?
I see only BindDynamic macto and it require object, and function.

Edit:
Binding event in blueprint works.
But how do I bind delegate that do not take any functions in code ?

Opps, sorry. I forgot to mention that you have to also bind that event with the delegate like so:

udn_delegate_example.png

You get an option to place the Bind node also when you drag off the event-dispatcher.

Hopefully that’s the missing piece!

Thanks!
But I figured that out later. (; But still it adds unnecessary complexity to blueprint, that for the most part I’d like to hide from end-user.

It would be nice if it would be possible to bind event in code just to object, without taking any function.
Or by just taking object and variables of which to delegate value.
Whichever would work.

I’ve seen that .Broadcast() can take variables as argument where delegate have one or more params.

I figured out it would nice addition since delegates can also, hm delegate values to to where they are used, and that would be extremely nice functionality.

Hmmmm… I’ll talk this out with some people, but at this time we don’t plan on adding something like this to the engine.

For the time being, you have to pick which one of these approaches advantages you more. I understand not wanting the blueprint users to jump through the extra hoops with delegates and personally would stick with your original plan.

I probably will have to use both for now. One when I need to pass values between events and other when I just need to trigger something in the same class.

Function events have one particular disadvantage:
They only really work in blueprint that derive from class where function event was defined. While delegate events works across all classes (which was functionality I really needed).

Second issue (although that actually might my lack of knowledge), I’m not sure if function events can pass multiple values when triggered, From code variable back to blueprint where they have been triggered.

Never the less thanks for taking it for consideration!