-
-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for relative position/rotation/scale keys for AnimationPlayer keyframes #1191
Comments
You can use a parent-child node structure to effectively get relative transforms. |
Combine it with a method call that updates position when animation loops and you can move objects with AnimationPlayer. Here's an example: It might be tricky in some cases, but it's definitely possible to do. |
In a single specific and unique situation, this might be true. However if you want to project wide add relative animation at any time, adding a specific parent node to all your scenes and nodes which might need relative animation, is just not really feasible. One of the many usecases I imagine for this proposed feature would be cutscenes, for instance. Character scenes often have a physics body with importants code as root node for a good reason. Now adding some other parent totally fucks up the whole scene and code structure. Just think about the interplay between moving characters and Area nodes for example. The much cleaner solution would be support of relative animation as proposed here. Animation keys that add their value to existing property values, rather than replace it. |
Wasted a couple of days just trying to figure out why animation working just fine in its own scene defaulting to 0,0 when instanced in a parent scene. I’m new to Godot, but it baffles me to no end, that this simple feature is still not implemented, the problem is from 2016, how is it not fixed yet? The solution is quite simple - if you instance animation to a parent scene all its coordinates should be relative if you did’t uncheck a checkbox, like “local coordinates” or something in Animation player. It’s simple and logical - why would I want to play my animation at default coordinates when I deliberately placed animated object not on those coordinates, man I’m frustrated. |
Relative keyframes have a lot of caveats that absolute keyframes don't. For instance, you may want only some of the keyframes to be relative, or only some of the tracks. There is a lot of complexity that isn't obvious at first, but will become apparent when someone tries to implement this. The animation code is becoming very complex lately (example), so I wouldn't hold my breath for this being implemented soon. |
If it wasn’t resolved from 2016 it seems it is complex, alright. But at least some experimental function where it should work logically if you checked the right box could be implemented I feel, because it ruins Godot for me: it becomes a nightmare to fiddle with every scene local/global coordinates and each time second guess yourself - is it not working because you did something wrong or the engine is broken. |
In 3DTransform, there is already a method to extract relative values as root motion, and it is often used. However, there is only one root motion per AnimationMixer, and we need to add the relative values in gdscript. If we could make this work for other tracks as well, it would theoretically be possible to extract relative values, but there are two necessary implementations.
Well, as long as the blend does not exist, 1 in the above can be implemented in a user-side script. Just animate the value with a dummy prop/track, calculate the delta and apply it to any property. |
This exponential behavior could be exactly what is desired with relative animations. The relative animation key value is probably supposed to be added to the current value, regardless what the current value is. That's what differentiates it from the absolute values the AnimationPlayer currently sets. If the user does not want to add to that value (or subtract from it using negative values), they can simply key in a 0. The AnimationPlayer would only blend the keyed values on the relative track, not the properties those values are then added to. |
@golddotasksquestions Probably you do not understand the problem correctly.
If you play the relative animation to this case, what should the final value ideally be? If you do not calculate delta, the animated values will be applied as follows:
The above should not be the result most people are looking for in relative animation. So you need to calculate delta as follows:
If there are no blends or crossfades, this can be calculated in gdscript, but if not so, more complex calculations are required as I commented above. |
Thank you for double checking, but I have understood. After I understood (thanks to your previous comment), I actually went back to this comment and crossed out my previous proposal, because I agree that's adding a lot of complexity.
I would go with this route. Because it's simple and easy to maintain and understand and to communicate. If the user does not want to end up at 40, they would have to use discrete blending (aka no blending), or add a key with value 0 in the frame before/after they have a key with value 10. Honestly the more I think about it, the more I would prefer this behavior. |
This would be doubtful. The problem there in particular is that the final value is changed depends on the Animation FPS, especially the number of frames is unpredictable unless you are in physics mode. |
So only allow it for physics mode and only update it on physics ticks? |
As long as delta is used, the final value is consistent independent of FPS. So, it should use delta. If there is a relative animation that changes from 0 to 10, applying it to an object with an initial value of 100 will always result in a final value of 110, and applying it to an object with an initial value of 200 will always result in a final value of 210, as long as there is no non-animation input to the object. If there are non-animation inputs, they will also be taken into account for consistent results. If the above relative animation is applied to an object with an initial value of 300, and the controller input once moves the object by only 5 during animation playback, the final value will be 315. It is definitely confusing / un-user-friendly when the relative animation values are linear transitions to begin with, but the actual applied values are exponential changes; How do you plan to create the keys in that case? So it will never be implemented as you said; The relative animation you have in mind and that of others are probably far apart. If you want an exponential change, simply create an animation using the baking easing option in AnimationTrackEditor, or setting a curve to the ValueTrackKey, or using a Bezier Track, and apply it as a relative animation with delta method. Then, if you really want a value like your method, simply create a user-side accumulator that accumulates the delta of the relative animation every frame, separate from the internal accumulator for blending, but it may be simpler to use |
I don't understand how this is supposed to work and how I would have to implement it. Nothing about it sounds "simple" to me. |
You must learn at least BASIC animation feature: how to use easing on AnimationPlayer (one of the methods of easing is written in the tutorial https://docs.godotengine.org/en/stable/tutorials/animation/introduction.html#edit-keyframes). Then you need to learn about root motion and get to know the actual relative animation use cases there; Relative animation should be an extended implementation from root motion. |
I seen more users asking about it for 2D projects (and I don't mean skeletal animation). I'm only familiar with root motion in a 3D context. |
Probably you do not understand correctly what people are asking about. Most of users understands that root motion is currently only available in 3D. What is being demanded is a 2D version of it, and I am saying that it is almost synonymous with relative animation. While 2D root motion has such proposal (#5303) and PR (godotengine/godot#65183), and relative animation is definitely a more flexible version of that. Relative animation is better than hard-coded 2D root motion which is only available for some properties. In other words, this proposal should be able to supersede #5303. |
Would it be possible for this to be a more general proposal - the option to set any track in an animation to be an "offset" track which makes it behave additively with whatever the starting value is going into the animation? |
I would like to reference my discussion here: #9005 |
I would like to note that while this technically can work to get relative movement with AnimationPlayer, it does not solve the problem of not being able to watch the overall animation play in the editor, which means you might need to sit through the entire animation in-game just to find out something is still slightly wrong at the very end, and it becomes trial and error. |
I'm making an attempt at implementing this feature, but I'm having a hard time because I've never even looked at the engine code before. AnimationMixer and AnimationPlayer are particularly hurting my brain trying to understand. I would love some suggestions and/or some guidance on this. I'm on chat.godotengine.org as sramey40 and also the official Discord server as rameynoodles. |
i would also like to add, that i am working on a game that used that approach (its a unity project). While it fixed the animation issue, and worked perfectly. but it opened a doorway for so many other issues, and it turned out its not even worth it.
i can go into detail with each one, and while you can fix each one of these with code, that that will easily turn from a 10 lines of code function, to up to a 1500 lines of code to write it. (Note, Unity's root motion works, but we couldn't use it due to a different topic but thats a different story). Now, i went brute forced my way through it, and it worked, but what i am trying to say, this solution is Not feasible, its feasible to fix this issue in isolation, but it not feasible at all for an actual finished product/game. Essentially for anyone that is making an animation heavy 2D game. obviously, Relative key frames for the animation player is the optimal solution, but honestly its probably very complicated and would take ages to implement, and quite frankly, for most use cases #5303 root motion, root rotation, root scale for 2D is probably mor than enough to cover most cases. as we can see in the title of this ticket itself which is "position/rotation/scale" keys. However, lack of 2D root motion is very much one of the things that is blocking our time from going to godot, for example. |
Describe the project you are working on:
A 2D platformer about a guy who works in a mine
Describe the problem or limitation you are having in your project:
I need my character's position to change along with an animation
Describe the feature / enhancement and how it helps to overcome the problem or limitation:
in the inspector window, when I try to add a keyframe for the position (transform) of the parent node (which is the player), when that animation plays, my character is teleported to that transform position
Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:
imagine this is an AnimationPlayer timeline for an animation named "move character"
---(keyframe one, Transform (x=0, y=0) )----(keyframe two, Transform( x= 30, y=40))----
now in my code for the parent node (my player) i would write
$AnimationPlayer.play("move character")
moves the character 30 pixels to the right and 40 pixels down from their position before the animation was played instead of teleporting the player to the coordinates of x = 30, y = 40 from the starting position of the scene.
If this enhancement will not be used often, can it be worked around with a few lines of script?:
Not really. There are workarounds that involve tweening but it's more considerably more complicated as you cannot easily sync the Character's animation to their movement on the plane, like you would be able to if this suggestion is implimented.
Is there a reason why this should be core and not an add-on in the asset library?:
Yes, because It really seems like it should be a pretty basic and standard feature given that the need to move to a specific set of static and unchanging pre-specified coordinates on the screen seems like it has very limited use compared to be able to move of coordinates relative to your character's starting position while undergoing an animation.
The text was updated successfully, but these errors were encountered: