That would be transposition. You would need to calculate the slope at each keyframe, transpose that, and then provide that as the new tangent for the new keyframes. But not every AnimationCurve can be transposed, as an AnimationCurve must be a simply-defined function in the key domain, but some curves would have transpositions that have multiple solutions or incomplete solutions.
Another way of fixing my issue would be to find a time for a given value. AKA the opposite of the Evaluate method.
But it doesn’t seem to exist. Do you know any way to do this ? I couldn’t find any.
This still has the problem that not all functions can be transposed. Some values of Y may have multiple or no values for X. Again, in your case, the function does not appear to be “strictly increasing” or not increasing enough for the evaluation you’re doing at the right end of the domain.
So what’s a solution for this ? I know it’s possible, because I’ve seen it in a unity made game. UI there goes in and out the exact same way: fast at first and slow in the end.
I used Cheat Engine to slow the game time, and if I enter/cancel menu while the UI is still moving, it will go the other way, properly, while having the correct expected speed.
In your case, have you noticed that your desired inverted curve function is basically (1f - curve.Evaluate(1f - x)) , assuming the diagonal is 0,0 to 1,1? In other words, it’s not just a transpose that is mirrored around the red line, but it is also a 180º flip of the whole diagram?
If you ramped some value in with y = curve.Evaluate(x), then you can ramp it back out symmetrically with y = curve.Evaluate(1f - x), or flipped with y = 1f - curve.Evaluate(1f - x). If you didn’t like either one, then just draw a companion curve yourself manually instead of trying to find the elusive transposition.
Trying to find a mathematical transposition of your particular curve is not the only approach to this, and indeed not possible in the general case for all curves, and honestly if you’re ramping Time.timeScalenobody is going to notice the finer details.
I tried using 2 different curves but it’s super difficult to have them so close that for a given time/value, the UI would stay at the same place. For quickly increasing functions like this, a tiny error can immediately move the UI half of the way.
Even at normal speed, I can easily see it’s wrong
The movement is perfectly smooth in the video, when changing movement direction, we can clearly see no “UI jumps”. And he keeps the same curve apparently, fast then slow, regardless of direction.
How could he have done this ? It seems way to perfect for it being another manually made curve.
I even slowed down the game to 1000 times, and it has litterally no jump at all. It has to be the same curve, right ? So it’s gotta be this one, correct ?
Currently I move my UI from point A to point B when it moves “forward” and from B to A when it moves backwards.
A and B are apart by a value of, say, 100, and UI only moves along the X axis.
That means I have the initial and final positions (which become the final and initial positions when moving backwards).
I have my one curve.
When UI moves forward, the distance between the initialPos and the current one should be 0 at t=0 and 100 at t=1
So say I want to go backwards when time is between 0 and 1.
I should set the initialPos to equal the finalPos, set the value to -100, and set the new time to : newTime = 1f - curve.Evaluate(1f - curve.Evaluate(oldTime))
So for a given time/value (red) I need to find the corresponding yellow values. I will be travelling the red curve with increasing time, and the yellow curve with decreasing time.
I can’t seem to make any of your calculations work in a way that would give me the right results, maybe I’m using them wrong ?
I believe I should only be using the “flipped” equation in my case, though.
Thanks again for the help, it’s greatly appreciated.
This is not related to the original question, but found this while searching for a solution to achieve the effect shown on this GIF, hope it helps others here for the same reason.
You can create this effect by storing the current time value that is used to evaluate the curve, and start the opposite effect from that time.
This also has the upside of working with every animation curve, because you essentially store a 0 to 1 value, and can use it to evaluate anything with a duration.
Sometimes, you don’t need to solve an impossible math problem, to create a fancy effect in a game.