How to prevent garbage collection of UMGSequencePlayer instances that come from UMG Widget animations.

Hi all.

I’m working on an on-rails shooter game, and I’ve noticed some hitches that come from the garbage collector.

I’ve added a subsystem to log what is being garbage collected, and one of the things I’ve noticed is a huge amount of deletions on UMGSequencePlayer objects.

Right now I only have 1 animation on my crosshair widget, which is triggered each time I shoot. It looks like the Play Animation blueprint node creates a new UMGSequencePlayer object each time it is run, and each of these objects needs to be garbage collected. I was wondering if there is a good way to avoid this.

My initial idea was to reuse the UMGSequencePlayer the first time the shoot animation is played by saving a reference, and then replaying the animation using it. However, from what I can see in UE 5.5 most of the functions in the UUMGSequencePlayer class are not exposed to blueprints (Play, PlayTo, Stop, Pause, Reverse…), so I didn’t find a way to do this in the widget BP directly.

I’ve then tried to do this in c++ :

  • First, in my widget I created a UPROPERTY for the UUMGSequencePlayer* returned by PlayAnimation:

UPROPERTY(BlueprintReadWrite)
UUMGSequencePlayer* ShootAnimationPlayer;

  • Then, when I need to play the animation, if ShootAnimationPlayer is null I play the animation normally, and save the reference:

ShootAnimationPlayer = PlayAnimation(ShootAnimation, 0.0f, 1, EUMGSequencePlayMode::Forward, 1.0f, true);

  • If ShootAnimationPlayer is not null (which means I’ve already played the animation once), I try to replay it:

ShootAnimationPlayer->Play(0.0f, 1, EUMGSequencePlayMode::Forward, 1.0f, true);

However, what I’m observing is that the first time the animation plays correctly, but the second time there is a hitch, and it doesn’t play the animation at all. Looking at the hitch, it looks like the TickManager variable is null when Play is run, which causes the hitch. Not sure why this is.

What I’m trying to find out is:

  • Is there a way to reuse the UMGSequencePlayer returned by the PlayAnimation node in blueprints so that I don’t have to garbage collect so many objects? The shoot animation can be played very often.
  • If this can’t be done in blueprints, can it be done in c++? If so, how?
  • This particular animation is super simple (just resizing the crosshair image over time to make it grow a bit and then go back to the original size). For this particular scenario, would it be better to write a function that does this “animation” instead of using the sequencer? (I’m still interested in the previous points for more complex animations, though).

Thanks, and regards,

Zoldar.