Scaling tween animation issue
Is there an existing issue for this?
- [x] I have searched the existing issues
Describe the bug
When I add a scale tween animation to an object or group in the event sheet and set the easing parameter to a value like easeOutBack, the object or group gets excessively over-scaled during the animation, far beyond the expected range.
I investigated the source code and found that in the addObjectScaleTween3 function, the tween is applied using exponentialInterpolation:
https://github.com/4ian/GDevelop/blob/3c63f9b6173418d9fee4468d08e048865bc8c6c6/Extensions/TweenBehavior/tweenruntimebehavior.ts#L852
When I replace exponentialInterpolation with linearInterpolation, the scaling animation behaves as expected.
My question, why is exponentialInterpolation used instead of linearInterpolation in addObjectScaleTween3?
The same exponentialInterpolation is also used in the addObjectScaleXTween2 and addObjectScaleYTween2 functions:
https://github.com/4ian/GDevelop/blob/3c63f9b6173418d9fee4468d08e048865bc8c6c6/Extensions/TweenBehavior/tweenruntimebehavior.ts#L915
https://github.com/4ian/GDevelop/blob/3c63f9b6173418d9fee4468d08e048865bc8c6c6/Extensions/TweenBehavior/tweenruntimebehavior.ts#L1008
Additionally, there seems to be an unnecessary _addObjectScaleXTween call inside the addObjectScaleTween3 function:
https://github.com/4ian/GDevelop/blob/3c63f9b6173418d9fee4468d08e048865bc8c6c6/Extensions/TweenBehavior/tweenruntimebehavior.ts#L815-L824
I'd like to understand the design decision before submitting a fix or change. Thanks!
Steps to reproduce
- Add a sprite to the scene.
- In the event sheet, set the sprite's initial scale to 0.001.
- Add a Tween object scale action to the sprite with settings:
To Scale = 1andEasing = easeOutBack
During the animation, the sprite scales up excessively beyond the intended size.
GDevelop platform
Desktop
GDevelop version
5.5.230
Platform info
No response
Additional context
No response
For instance, if you take 2 tweens with a "linear" easing:
- one going from a scale of 1 to 4 in 4 seconds
- one going from a scale of 1 to 2 in 2 seconds
after 2 seconds you would expect both to be at a scale of 2, but with a linear interpolation the 1st one would actually be at a scale of 2.5 = (1 + 4) / 2.
This is because, a one-time scaling is a multiplication (not an addition). So, a progressive scaling over time is an exponential.
I think the issue is that the "easeOutBack" easing may not necessarily fit any case and GDevlop doesn’t allow to draw custom easing functions.
For instance, if an easing has a peak of 1.5, with a linear interpolation:
- going from 1 to 2 would reach 2.5 (which is 1.25 times bigger than the target: 2)
- going from 2 to 1 would reach 0.5 (which is 2 times smaller than the target: 1)
So with a linear interpolation, the easing would be stronger in one way than the other.
In your case, since the side effect of using a linear interpolation reduces the easing effect and allow you to get the result you want, you could tween the width and height of the object. These tweens use a linear interpolation because they can be seen as a translation of the object bounds (for instance to animate a life bar).
Thank you for the explanation, I can't say I fully understand all of it yet, but I will revisit the topic later. I will also try using width and height tweening as suggested.
Previously, I developed a mobile game using a different game engine. I really like the concept of GDevelop, so I thought it would be a great learning experience to recreate the game here. However, I encountered this scaling issue right at the intro screen.
I've recorded a video showing the difference. Once I replaced exponentialInterpolation with linearInterpolation in the GDevelop source code, the animation behaved exactly like it does in the other game engine, which is the behavior I need.
Would it be possible to make the interpolation function configurable in the scale tween action, so we could choose between exponential and linear?
Here are the comparison videos:
Scale animation using easeOutBack in the other game engine:
Scale animation using easeOutBack in GDevelop: