Closed Alex-doc closed 4 years ago
@Alex-doc ~ That's too much complexity IMO, and can be done with just adding an additional parent Node2D
...
That being said, it would be nice to be able to, say, have a move_up
animation that would both animate a sprite and move it up from its current location. :wink:
I see, you are right. Adding a parent Node2D
does exactly what I meant, so the implementation in the AnimationPlayer
would be pointless.
Can you specify a bit on the move_up
animation? Can't that also be achieved with an animated sprite with AnimationPlayer
attached?
(apart the discussion about the move_up,
I feel the issue can be closed)
@Alex-doc ~ I mean, if this feature request gets implemented, it would open a wide range of nice ways to get movement code out of _process
/_fixed_process
.
@bojidar-bg I think something like this move(vector2(50,50),5.0)
50,50 is offset and the second one is seconds
@mohaalak wouldn't that better belong to a Schedule
module?
Something with two main functions, a delayed call and a call over time.
For instance:
Schedule.delay(function,time)
so it can be done in a single for loop (scheduling set_pos(10*i,10*i)
)
Or better, with the other main function I have in mind which essentially does the same thing over time:
Schedule.task(function,time)
.
Each of the functions would get the current time but do opposite things:
delay
would wait for the time to end and then call this function the other one same but would call it (each frame?) for time
Sorry for the off topic in the issue but I think is quite worthy as idea(and some kind related), if you are interested I'd open a new issue over it.
P.S. I'm not sure if Object::set()
can actually call script functions, but the idea is something similar.
this one might actually better fit
@mohaalak @Alex-doc You can already make the so-called "function tracks" in the animation player... also, Tweens are just going to get better :wink:
I guess this issue should be left open though, since it is a nice feature too.
@Alex-doc look at tween example in demos
You are misunderstanding the way the locations in the nodes work. Every node is positioned relative to its parent. When you animate the position of the root node you are animating (and thereby overwriting) the position of the scene relative to its parent. I understand that it's confusing at first (I made the mistake in the beginning as well), but once you understand how it works it's obvious that the right way to solve this is by simply not animating the position of the root node but use a Node2D as a root and animate the other nodes relative to it.
@Warlaan, read the comments above, bojidar-bg already suggested the solution and the topic was then solved, we then discussed about some kind of scheduling function. Which is out of the scope of this issue. Closing it now, since I thought it was already...
Actually, I believe this would be a useful addition.
Having to add a parent node so that the animations become "relative" makes me have to change my scene hierarchy when I come back to add animations to polish the game, which causes necessary code changes.
Yes, I could use Tweens instead, but the strong point of the AnimationPlayer system is that you can preview the animation in the editor (instead of guessing the numbers that look good and running the game to see results when using Tweens).
It would also help with creation of re-usable animations. For example I just created a "shake" animation. It moves the root item left and right quickly (the only track is ".:transform/pos"). If a "relative" mode was implemented, I could use it immediately on any node with an AnimationPlayer. However because there is no relative mode, then I have to create a parent node of the original node instead so that it doesn't get it's position reset to 0,0
Without a relative mode, I think it is limiting the places where AnimationPlayer could be used.
@bojidar-bg also stated it should be left open
I guess this issue should be left open though, since it is a nice feature too.
Reusable animations sounds pretty good.. Reopened. The upcoming 3.0 excuses breakages that could be a nice occasion to discuss this feature.
Note that we have to discuss the following:
I think the artist should be setting the last frame to match the initial state (which I think it should be on frame 0) so, no auto-reset (unless looping)
the animation's "ghost parent"(read as point from which relative animations will move) should move its location. If two are playing on the same object, I would be expecting the same behaviour we have with non-relative right now.
I'd put a flag in the animation's property.
Note: My opinions are expressed before actually going to read the current animation's code. Will likely change after I'll take a better look into it.
I think you are underestimating the importance of the first point. When you run an animation in the editor the scene gets changed. You have to manually reset the scene (or depending on how your animation is built reset it to frame 0) before you can save it again, otherwise you will save the wrong initial state for the scene. For example if you have an animation that turns an object invisible and you play it in the editor you need to make the object visible again before saving the scene or else your object will be invisible everytime it is instanced.
Also I don't understand what you mean that the artist should be setting the last frame to match the initial state. The first use case that came to my mind was doing a walk animation for a game where you can only walk from square to square (like in Pokemon or Sokoban). That animation would of course not end with the same state as in frame 0 because modifying the position would be the whole point. And I would certainly hope that if that animation was looped it did not reset its position at the end but continue from the new position.
This example shows how dangerous it is to try and build a magic solution for specific use cases because you can never know what use cases other people are going to come up with. So I would strongly suggest using a very simple mechanism that works in a predictable way and improving it from there on.
In this case I would suggest that a "relative" animation track simply performs one step whenever it passes frame 0: It takes the property it is meant to modify and adds the current value to every value in the track as an offset. That way a single relative animation would work just as requested while unexpected use cases (like two animations running at the same time) would work predictably the same way as current animations because they would be using the exact same system.
In order to allow more than one relative animation at a time that solution could be extended later so that after applying one frame the animationplayer notes which value it set the property to, and when the next frame is to be applied it adds the difference between the value it set and the value it finds (modified by physics, other animations or scripts) to the offset.
The biggest drawback would be that not for every property the correct operation to apply an offset would be an addition. For example if you were to animate a matrix you would have to multiply the offset rather than add it. Or if you were to modify a bool flag you would probably want the flag to be flipped (otherwise a relative animation would be the same as an absolute one).
In this case I would suggest that a "relative" animation track simply performs one step whenever it passes frame 0: It takes the property it is meant to modify and adds the current value to every value in the track as an offset.
Yes, this is how I imagined it would work. The current value at frame 0 of the property of the object that is being animated gets added to all key frame values in the animation track.
And yes, different property types might require different operations.
Example of how the adding object value to keyframe would work: (I guess you all get it already though)
If a relative animation had keyframes on pos time = 0 seconds, pos = (0, 0) time = 5 seconds, pos = (500, 0)
An object has pos currently (200, 100) gets the above relative animation played on it, then the keyframes become time = 0 seconds, pos = (0 + 200, 0 + 100) = (200, 100) time = 5 seconds, pos = (500 + 200, 0 + 100) = (700, 100)
And the animation is played as normal, resulting in the object being moved right 500 units in 5 seconds from its initial location.
Regarding point 1) the problem (as I understand it) is that when editing if the relative animation is being played in 'relative' mode, then just playing the object multiple times would keep moving the object around possibly further and further from beginning point.
The way to fix that is to have 'relative' mode be a flag that is used at runtime only. When editing, it would only be a flag to set that is saved, or maybe 'relative' is just an option in the play() method to call at runtime.
The downside of having 'relative' mode available only at runtime is that you wouldn't be able to edit 'relative' animations in abritary scenes where the object to be animated in the editor is not at (0, 0). When editing 'relative' animations you'd have to use a separate scene with the object to animate at (0, 0) (well it doesn't have to be at 0,0 - depends on the animation to create if you want it to jump at the beginning) ... but this would be worth it because the resulting animation would be re-usable and applicable to multiple scenes / objects in different starting positions later.
Well, otherwise editing relative animations would have to make the editor go into a special mode where it remembers the initial position and resets its as @bojidar-bg said. I think that could be confusing though as the object position in the inspector wouldn't match the values in the keyframes.
After reading @Alex-doc 's comment again:
the animation's "ghost parent"(read as point from which relative animations will move) should move its location.
I kind of get what you're saying. How to implement though I have no idea yet.
EDIT: Actually I think @Warlaan has the answer here:
In order to allow more than one relative animation at a time that solution could be extended later so that after applying one frame the animationplayer notes which value it set the property to, and when the next frame is to be applied it adds the difference between the value it set and the value it finds (modified by physics, other animations or scripts) to the offset.
This will correctly allow other movement code to work at the same time as relative animations
Another thought: Relativeness might even be set on a per-track basis. Ex. absolute rotation / scale / opacity, but relative position.
Going deeper: It could even be per key!
Ex. an animation to move from wherever you are to pos (200, 200)
(you could even have it move back to start position with a third relative key = (0, 0) )
This would be immensely useful for a lot of things and is easily implemented using the same ideas above and just adding a flag per key.
EDIT: (crazy thought) ... then instead of a flag on each key of either absolute or relative, there would be a weight of absoluteness from 0 to 1. Values in between would be weighted. .... I'm not even sure if that is useful LOL (I'm imagining swirling coins dropped by monsters on the floor up into the gold amount display at the top of the screen .. absoluteness would gradually increase.), but being able to set either absolute or relative per key would definitely be useful as in example above.
EDIT2: With the addition of relative / absolute keys, then the Animation system would almost be able to replace entirely the Tweening system with the advantage of being able to preview the animations and ease of creation using the Editor. Tweening's advantage was/is that you could tween from current values to absolute values. With relative keys, the Animation system will also allow that and also allow creation of complex finely tuned reusable animations that if one were to try hand coding with Tween it would be too painful to even try. Add some tween-like methods to dynamically create animation tracks to the Animation system and then it could completely replace Tweening.
Welp, I never meant it to not be per-track.... Also, I fully agree that we have to make it add the change in the two positions of the animation to the position the object happens to be in. That way, we would be able to have multiple relative animations and animations on rigidbodies just fine... :smiley: I think it would be pretty terrible to work with absolute and relative keys at once (relative to what? last absolute key? position of the object (when??)?). I do understand the usefulness of the idea, but, can we reunite the two?
Relative would mean relative to the initial object position (not the last absolute key).
More examples:
Animation to move from wherever you are to pos (200, 200) and back to beginning:
Animation to grow by 20% of current size and then scale to 100% of actual size (assuming relative scale is by multiplication)
The question is how the positions are added. As I understood the posts so far I thought that the idea was to actually create an invisible base node and have the built-in mechanisms of the node system apply the offset. Which would obviously have the advantage that it wouldn't be necessary to rewrite the code that combines node properties, since transforms, visibility etc. are already applied to child nodes.
But imho that would introduce more "magic" code since it's less obvious what happens when two relative animations are running at the same time. Do both try to access the same invisible offset node or does each add their own?
I don't know for sure if you are referring to my post or chanon's, but if it's done the way I suggested (the basic one, not the extended one) running two relative animations at the same time or combining relative animations with physics would not be possible, since the whole animation would be relative to the location the object was in at frame 0. The extended version would work however. Just keep in mind that this would mean that the animation player would have to run in the _integrate_forces-phase, not in idle or fixed mode.
By the way: I always thought that this was what the Transform Track was supposed to be, but I never got it to work (never tried really hard though). Did I misunderstand the feature or is it simply broken?
For this animation:
Animation to move from wherever you are to pos (200, 200) and back to beginning:
Using the method of adding initial object position to key values, if applied to an object with beginning position of (300, 100) the keys would become.
final animation keys:
This results in the object at (300, 100) moving to (200, 200) and back to (300, 100).
@chanon But, what about animating a rigidbody, but still having physics apply to it? :smiley: Or, running two relative animations at once?
@bojidar-bg Again, I think with the following it should be able to do it:
In order to allow more than one relative animation at a time that solution could be extended later so that after applying one frame the animationplayer notes which value it set the property to, and when the next frame is to be applied it adds the difference between the value it set and the value it finds (modified by physics, other animations or scripts) to the offset.
But absolute keys wouldn't mix well with having anything else modifying the object's position. (Just like the current animation system doesn't mix well with having anything else modifying the object's position.)
There is still a lot of usefulness though in being able to set keys to be either absolute or relative. Eg. Fade in from current opacity to 1.0. Lots of things that you would have to resort to Tween usually.
In the case where one doesn't need to mix the key types, to help when editing, there should be a flag to consider all keys in a track relative or absolute so you don't have to mark each key one by one.
If it's done the way I suggested in the quoted paragraph it should work fine in combination with any other mechanism moving the object, since the animation would effectively move the object from it's current position for the difference from the current animation frame to the next.
Nevertheless I would recommend doing it step by step. It's good enough to have a relative animation first. Allowing to mix more than one, mixing it with physics or making the relativity scalable are great additions, but imho they are additions nonetheless.
Yes, just having relative animation is a great start!
My idea to have different key types is just an addition that would be useful in some cases. (Just in cases where you want to animate from current value to an absolute value and maybe back again etc.)
But relative animation tracks in general would be a great feature already. And with the ability to mix in with other movement, then that already would take the Animation system to another level of usefulness.
That can be added later though. The simplest way to begin implementing is just to use the "add object initial position to key values" for relative tracks and then add the ability to mix with other movement later.
The next problem though is how to apply the relative values for each track and how would the animation system know.
Ex. For position it must add the relative values in. For scale it should multiply the relative values in. (right?) For rotation it should add them in. (right?) For opacity also multiplication.
How does the AnimationPlayer (and the editor) know? Is it hard coded? Is there some kind of registry to look up? Does the person who creates the animation specify it for the animation track in the Animation .. possibly with correct defaults for known properties?
(continued) Basically, is the relativity being specified in addition to the beginning value, or as a factor (i.e. multiple) of the beginning value. It is actually possible that both could be useful for the same property in separate instances. Ex. instead of object moving up 100 pixels, we might want it to move up 2 times it's current height.
Then for some property types a simple addition or multiplication isn't enough ... eg. for Color changes. How would a relative color change work? Maybe there has to be ability to specify a script function?
Again, I'm thinking too much. Lets just implement for simple properties first.
So far I only see three algorithms:
For boolean values and matrices there's only one viable mechanism, so technically a toggle button to switch from multiplying to adding that only appears for numbers or vectors would suffice. But I assume people would expect that the system creates some tracks in the right setting automatically, since it would totally confuse beginners if a position was multiplied by default or a scale added.
Relative color changes should work the same way vector maths works in a shader. Every component is treated separately, so addition and multiplication are just per-component scalar operations. After all that's what happens when you use a texture in multiply-mode.
EDIT: colors should probably just be treated as vectors
@chanon Don't over do it, we aren't trying to replace the tween system completely, nor to make all animations possible with just an animation player :laughing: Tweens are still going to be useful, even after this is over. We would basically have a per-track setting about add/multiply/etc. changes.
Looks like this is all hashed out then 😄
Is this issue still relevant? If so it would be good to have a TL;DR edited into the OP for clarity (and maybe the issue titled edited appropriately if more details are needed).
Agreed, it would be very useful.
Having to add a parent node so that the animations become "relative" makes me have to change my scene hierarchy when I come back to add animations to polish the game, which causes necessary code changes.
Yes, I could use Tweens instead, but the strong point of the AnimationPlayer system is that you can preview the animation in the editor (instead of guessing the numbers that look good and running the game to see results when using Tweens).
These exact reasons applies to me and some friends too. Also, the AnimationPlayer is quite powerful now, with the Beziers and other nice things, so we'd love to see a relative option for it.
Is there another game engine that implements something like that successfully?
I'm not sure now, but I think the capture option (in the update mode/interpolation dropdown) might be doing this.
@bojidar-bg I am looking at the docs, and searching in the issues open and closed, and can not find a reference to that capture option. Do you have a link to get information about that? Thanks in advance.
from @chanon post:
For this animation:
Animation to move from wherever you are to pos (200, 200) and back to beginning:
- key1: relative key with position value = (0, 0)
- key2: absolute key with value = (200, 200)
- key3: relative key with position value = (0, 0)
Using the method of adding initial object position to key values, if applied to an object with beginning position of (300, 100) the keys would become.
- key1: position value = (0 + 300 , 0 + 100) = (300, 100) (it is a relative key, so object position is added)
- key2: position value = (200, 200) (it is an absolute key, so object position is not added)
- key3: position value = (0 + 300, 0 + 100) = (300, 100) (it is a relative key, so object position is added)
final animation keys:
- key1: (300, 100)
- key2: (200, 200)
- key3: (300, 100)
This results in the object at (300, 100) moving to (200, 200) and back to (300, 100).
I really like this idea. And I think this will be a very useful feature.
From @Warlaan post:
I think you are underestimating the importance of the first point. When you run an animation in the editor the scene gets changed. You have to manually reset the scene (or depending on how your animation is built reset it to frame 0) before you can save it again, otherwise you will save the wrong initial state for the scene.
While an animation is being tested in the scene editor, I think that the "better behavior" should be that no properties are permanently changed. So, when the tested animation is stopped, all properties should be reset to their original values. Unfortunately, I think that Godot currently does not implement it like that.
2019 / 08 / 2 😥 still hoping for that feature
@ticnew Please don't bump issues without contributing significant new information; use the +1 reaction button on the first post instead.
roger that boss
Apparently, for 2D, this 2D Root Motion (https://github.com/godotengine/godot/issues/27515) would solve the problem, the only thing against would be the need to have an AnimationTree node in the scene, of course the need of it in 3D is understandable, but for 2D the engine could have a Root Motion property linked directly to an AnimationPlayer, since that there are no bones to worry about, just simple frames.
I still don't understand why it's so hard to implement this feature, even GameMaker 2 makes it easy to animate something like that. There are situations where you need to set a long animation for the KinematicBody2D and it still needs to check for collisions with the level in the meanwhile. I solved this using the move_and_collide with an exported variable, but it would be interesting to have this implemented as a built in feature by the engine. And using a Node2D as parent for this is a kind of clumsy.
I believe the solution could be a "local position" variable that implements move_and_slide or move_and_collide internally, and that takes into account AnimationPlayer update and interpolation properties in the calculations.
In the reddit community there is always someone asking questions about this issue, perhaps this may be indicative that this feature is indeed essential for making some games.
A recent example: https://www.reddit.com/r/godot/comments/dwcs2l/2d_fighting_game_push_collision/
I believe the solution could be a "local position" variable that implements move_and_slide or move_and_collide internally, and that takes into account AnimationPlayer update and interpolation properties in the calculations.
The issue is that we'd need to add "local" properties for every property that someone might need to animate in a local manner. This obviously doesn't scale, and would clutter the Inspector a lot.
Feature and improvement proposals for the Godot Engine are now being discussed and reviewed in a dedicated Godot Improvement Proposals (GIP) (godotengine/godot-proposals) issue tracker. The GIP tracker has a detailed issue template designed so that proposals include all the relevant information to start a productive discussion and help the community assess the validity of the proposal for the engine.
The main (godotengine/godot) tracker is now solely dedicated to bug reports and Pull Requests, enabling contributors to have a better focus on bug fixing work. Therefore, we are now closing all older feature proposals on the main issue tracker.
If you are interested in this feature proposal, please open a new proposal on the GIP tracker following the given issue template (after checking that it doesn't exist already). Be sure to reference this closed issue if it includes any relevant discussion (which you are also encouraged to summarize in the new proposal). Thanks in advance!
Why is this issue closed after being open from 2016 to 2020 ? Its still not solved. You still have to wrap all your nodes that you want to animation in another rote node, which wouldnt be necessary in the first place. I dont even see ANY reason that lead to this issue being "closed" and "archived" in the first place. I see a lot of discussion and good arguments for having this "feature" and thats it.
@AncientSion There's already a proposal tracking this: https://github.com/godotengine/godot-proposals/issues/1191
I dont even see ANY reason that lead to this issue being "closed" and "archived" in the first place. I see a lot of discussion and good arguments for having this "feature" and thats it.
No matter how well-received feature requests were, we decided to unify them in a single repository (godot-proposals). The main Godot repository is now used for bug reports only.
Hello! I feel AnimationPlayer is missing a "relative position" feature. To be more clear: the actual location of the animation would be relative to the local position instead of the absolute world position.
For instance, it would allow to create platforms that move in a circular pattern without remaking the animation every time for each platform.
It surely can be obtained with Tween but is not as immediate and user friendly as it would be to have it in the AnimationPlayer directly.
Which would be the most elegant way to implement it?