-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
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
Root motion translation does not consider current rotation of object which will be applied root motion #58061
Comments
|
Hi, in Godot4 Beta6 this still shows the same broken behaviour. Cannot confirm the fix. |
@LasseSchnepel Can you send MRP or video? FYI, there is a DemoProject that shows that the rotation itself is gotten correctly. #29458 (comment) |
Hi Tokage, my assumption is that when I play the animation in the player (without the tree or with the root motion), the movement looks good. In your example project, the figure rotates and moves constantly forward. When used with root motion, your figure walks along a circle. I would expect that the figure moves as it would with the normal animation. (but with by the mesh at 0/0 and moving the outer node). This is also how root motion looks in all other engines afaik. The rotating while moving forward animation is nothing one could easily animate in e.g. blender. In blender I want to walk my figure on a circle and then have Godot replicate that movement with root motion. I attached an example project of mine (even though it is Godot.NET, is uses no .NET code, so should be usable without .NET): |
@LasseSchnepel Thanks for the project, that is a good reference. After looking into it: And I found several problems unrelated to this issue:
In any case, thanks for a good reference project. I don't see the need for any new implementation for root motion rotation for now, but I feel that the documentation needs to be a bit more detailed on how root motion is applied. Footnotes
|
Hi @TokageItLab , thank you for checking on my project. When I take your zip file and run it, I still see the same issue:
If I add Isn't the |
I have not added current rotation there yet, so you can just add it.
I don't think so, the extracted value as the root motion is not yet affected by the current rotation. So the correct process is to blend the animations under the assumption that they are all facing the same direction (means be not affected by the current rotation), and apply the current rotation on the script side after. The problem would be that the StateMachine never actually plays the next animation until the end of the animation. Yes, maybe retrieving should be done each time, but I don't think that is the role of the AnimationTree. As explained in #29458 (comment), it is easier to get the object to which the root motion is applied on the script side, and since the object is not always only one, I do not think that AnimationTree should have that role. I think it would be sufficient to connect the retrieving method to the transition signal of the StateMachine. |
Hi @TokageItLab, if I understand you correctly, rootmotion will never work with the statemachine. I struggle to understand, how I should solve a standard character animation system without a statemachine and by blending. Can you make an example? |
@LasseSchnepel It is natural that root motion including rotation will not work correctly if there is xfade in the transition. Previously, the default value of xfade for NodeOneshot has been changed 0.1 to 0 for that reason. Interrupting animation is not yet implemented in StateMachine. For that reason I use NodeTransition and NodeOneShot a lot in my projects instead of StateMachine. (StateMachine could be improved in the future) At least with NodeTransition/NodeOneShot and an xfade of 0, it is possible to fire the animation and retrieve current rotation at the same time, but I am not sure if it matches your use case. At least, I think that rotation by root motion is a special case, like the spinning sword attack animation does not change the actual direction of the player. So I think it is common in 3D Games to manage the rotation on the script side, without using only root motion. |
@TokageItLab I had played around with the godot's source code a bit and was able to fix the root motion behavior just by storing the global skeleton basis at the start of the animation and using it to xfom the translation passed to the rootmotion object. You can see in this commit. With the fix this line was enough to mimic the behavior we have in Unity using your sample. player.transform *= root_tr However, I'm not confident enough in my fix to submit a PR. I imagine this would be a breaking change and should be enabled by a flag. I'm also not familiar with Godot's contribution guidelines. |
@HitalloExiled The current_rotation needed to move the root motion is not always global_transform. For example, if the player is a child of a node in a rotating field, parent_rotation is required. Therefore, it still should be handled by the GDScript side and not by the AnimationTree side. |
@HitalloExiled Also, What is needed in Godot core is not to default to code that can only be used for specific use cases, but make it easy for extracting values that are easy to use on the GDScript side. |
@TokageLab The transform used as a reference could be defined through a property.
I would agree that this could be done via script if it weren't for the issue with xfade (that my fix yet doesn't solve it, I'm working on it.). It is currently not possible to work around this limitation. And as stated in another comment, in Unity it just works. And it seems to me to be possible to implement the same behavior in Godot without compromising anything.
I'm ok with that. we just need the relative delta of translation. |
It is not acceptable to add it to core just because you want to use the same code as Unity. Godot is not Unity, and all game engines don't need to handle root motion in the same way.
So I say your suggested code is certainty not worthy to be included in core yet. As I said above, what should be implemented in the core is to make it easy to get the values that can be used on the GDScript. Therefore, I agree with what you said in #29458 about getting the transition(xfade) position values from StateMachine/NodeTransition/NodeOneshot, and I recommend that you write that in proposal (https://github.com/godotengine/godot-proposals). |
I just want to show that it's possible and requires minimal changes.
I already created the proposal, but I see it only as an enabler to work around the current problem. Having said that, I can create another proposal requesting the changes on the root motion, this should give an idea of the size of the need. |
I recently found this issue with RootMotionView, so I'm looking into it again. So, player.transform.basis *= tree->get_root_motion_rotation();
player.transform.origin += (tree->get_root_motion_rotation_accumulator().inverse() * player.transform.basis).xform(tree->get_root_motion_position()); I think it will work. (I will send a PR to add the accumulator later.) |
Godot version
v3.4.2.stable.mono.official
System information
Windows 10, GLES3, RTX 3060
Issue description
In the current state, root motion always returns a transform with the delta of rotation and translation.
This works fine for most scenarios.
However, when an animation has both rotation and translation, things get complicated.
It is necessary to save the orientation at the beginning of the animation, apply the translation relative to the saved orientation while rotating the object using the root motion delta rotation.
Example:
This can work on animations where translations end up with no delta translation and small/zero xfade.
Otherwise, if the animation ends with some amount of delta and/or xfade, things will break.
Digging on the issues i found this PR #29458 that tries to fix that.
Which unfortunately appears to have been abandoned.
Steps to reproduce
Create a root motion animation only with translantion.
Create a root motion animation with translantion an rotation.
create one state machine that travels from one state to another.
applies thee root motion to the transform
Minimal reproduction project
Example.zip
Presse W to walk and A or D to turn.
The text was updated successfully, but these errors were encountered: