How can I do this UMG animation?

I have some buttons that are sized depending on the text within them, and I am trying to implement the following animation in way that would work with any amount of text in the buttons:

Since the animation here that moves the “Accessory” button left is using absolute values it don’t work if the size of the “All” button changes. If the size of the “All” button changes we end up with this:

You can see it doesn’t work at all because the absolute values used previously only work when the “All” button is that exact size.

Perfect world I would be able to modify these absolute position values at runtime depending on the desired size of the “All” button. But it seems like this is impossible?

How can I do this animation in a way that will work for all button sizes?

Thanks in advance!

I can think at least 2 ways to approach this but there might be more.


Perfect world I would be able to
modify these absolute position values
at runtime depending on the desired
size of the “All” button. But it seems
like this is impossible?

It’s possible but not via widget animation per se. In order to pull it off you’d need to know the Desired Size of the widget and its relative location in the parent:

333405-screenshot-3.jpg

So placing the elements in a canvas (perfect for moving things around!) would the easiest since you have direct access to the (almost) pixel perfect data. Alternatively, you can animate render transforms - probably more fiddly overall, though.

Now, you cannot feed widget animation values dynamically, and widgets don’t have timelines (admittedly, you could have an actor send timeline progress to the widget). But you can have a fixed length widget animation (here 2.25s + Map Range to get Lerp friendly values) and Lerp between any value:

You know the size of the container (or calculate it from absolute → local, depending on how the menu hierarchy), you know the desired size of the widget to shift and you know where in the canvas it’s sitting - canvas slot position.

If the child is anchored to the left hand size, it’s a matter of moving it to the left by that much. Anchored to the centre, you’d need to adjust for half the widget width.


Another option is to use panel slots. When a widget is added to a panel (a Horizontal Box, lets say), the HB creates a slot for that child and the child must respect the rules of that parent slot.

Above, the 1,3,4 are set to size .1; setting them to size 0 would allow the second button to take all the space there is. You can animate Size but figuring out how much space these should take will be more difficult.

And here’s another method where we don’t care about anything at all and just interpolate anchor offset anchor instead:

Image from Gyazo

Store the initial position of the clicked widget so you can animate back when needed.


Obviously, this should be structured better; with user widgets instead of buttons and dispatchers to filter out what is being clicked. Just a click mock-up.

Thank you for the responses! Really unfortunate that we can’t just modify the animation object itself, seems like a really common thing that many people would want to do.

Please correct me if I am wrong but for solution 1 since we are using a lerp we would lose any sort of curve that the original animation had right? Like we would be linearly interpolating between the two position values instead of the curve that I set up in the animation? I wanted a “ease in, ease out, curve” not linear to make it look more natural.

Same thing for solution 3 right?

I suppose though I could probably create a float curve and sample it myself for either solution 1 or 3?

Cheers!

Yep this works perfect, Thank you! Huge shame that there is no way to do this using the UMG animation class directly. I honestly can’t believe something so simple has to be done custom.

Please correct me if I am wrong but
for solution 1 since we are using a
lerp we would lose any sort of curve
that the original animation had right?

Yes. In this very case the widget animation is a linear 0-1 alpha. Using a timeline and piping the data into the widget is not a bad idea, though - all the control you will ever need.

If that’s not possible, the widget animation’s linear progress can sample an external curve:

And this is much neater and easier to control than interpolating on Tick, which would be pretty wild and inconsistent.

Exactly the same issue I resolved using GetGeometry. Worked like a charm:

No zomali