Skip to content

Root motion implementation#24201

Open
Hilpogar wants to merge 37 commits into
bevyengine:mainfrom
Hilpogar:root-motion-part-3
Open

Root motion implementation#24201
Hilpogar wants to merge 37 commits into
bevyengine:mainfrom
Hilpogar:root-motion-part-3

Conversation

@Hilpogar

@Hilpogar Hilpogar commented May 8, 2026

Copy link
Copy Markdown
Contributor

Objective

Closes: #23355
Final step for the root motion implementation !

Solution

Add the RootMotion component that stores the informations about the root motion for the current frame:

pub struct RootMotion {
    /// Translation delta with the previous frame.
    pub translation_delta: Vec3,
    /// Rotation delta with the previous frame.
    pub rotation_delta: Quat,
}

Add the RootMotionMode to control how the RootMotion is extracted. There are 2 modes, one with only translation and one with translation and rotation :

pub enum RootMotionMode {
    /// Extract only translation from the root target.
    Translation,
    /// Extract both translation and rotation from the root target.
    #[default]
    TranslationAndRotation,
}

Add the field root_motion_target and root_motion_mode to the AnimationPlayer:

pub struct AnimationPlayer {
    <...>
    root_motion_target: Option<AnimationTargetId>,
    root_motion_mode: RootMotionMode,
}

Testing

The test_root_motion tests the extraction of the root motion in a configuration with 2 blended clips. The test is done once with the clips running forward and once backward.


Showcase

You can run the root_motion example to see it in action.

@alice-i-cecile alice-i-cecile added C-Feature A new feature, making something new possible A-Animation Make things move and change over time M-Release-Note Work that should be called out in the blog due to impact labels May 8, 2026
@alice-i-cecile alice-i-cecile added this to the 0.20 milestone May 8, 2026
@github-project-automation github-project-automation Bot moved this to Needs SME Triage in Animation May 8, 2026
@alice-i-cecile alice-i-cecile added X-Contentious There are nontrivial implications that should be thought through S-Needs-Review Needs reviewer attention (from anyone!) to move forward S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels May 8, 2026
@Hilpogar
Hilpogar force-pushed the root-motion-part-3 branch from 70ddfd8 to 8b7f259 Compare May 9, 2026 19:01
Hilpogar and others added 4 commits May 10, 2026 07:30
Co-authored-by: François Mockers <francois.mockers@vleue.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for someone to check if this asset is allowed to be committed or if it needs to be a remote/web asset.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this because of potential copyright or licensing issues with the model, or is it just to avoid overloading the repository? If it’s a licensing issue, please note that this is simply the existing fox model to which I’ve added root motion to the running animation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s to do with repo size / bloat. E.g., see #23567 (comment)

I don’t know the bytes threshold but AFAIK, I think bevy wants to avoid putting more assets in this repo if possible.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a comment indicating what the changes to the file are here. Notably in case it ever needs to be modified or understood in the future. Otherwise it will be hard for future contributors to comprehend why this is a separate file.

Personally I think a FoxRootMotion.md that explains the steps taken to create the new file from the original would work.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with that. This is not so big that I think we have to move it out though IMO, but clear guidance here would have been nice.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've created a ForRootMotion.md containing the instructions to recreate the file. This is a very slight modification of the file, do you think the instructions are clear enough?

@Hilpogar

Copy link
Copy Markdown
Contributor Author

I realized that removing the AnimationPlayer from an entity could "leak" the RootMotion component. So I added a hook to remove it with the AnimationPlayer. I've also added the cleaning behaviors in the tests.

@emberlightstudios

emberlightstudios commented May 19, 2026

Copy link
Copy Markdown

Thank you for implementing this....

Other game engines that I have used define the root motion behavior on a per clip basis. But here we are doing the graph evaluation first to blend clips then extracting the delta at the end. I think this is a very clean design. Well done.

I don't really have much to add. Maybe in the example you should put the apply_root_motion in PostUpdate and run it after AnimationSystems, but that's about it.

@Hilpogar

Copy link
Copy Markdown
Contributor Author

Good point, I change that 👍

@ChristopherBiscardi ChristopherBiscardi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This actually looks good, and I'm approving with the exception that I feel it is important to write more documentation around what/why the FoxRootMotion.glb exists and how to recreate it in the future if necessary.

Comment thread examples/animation/root_motion.rs

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a comment indicating what the changes to the file are here. Notably in case it ever needs to be modified or understood in the future. Otherwise it will be hard for future contributors to comprehend why this is a separate file.

Personally I think a FoxRootMotion.md that explains the steps taken to create the new file from the original would work.

Comment thread crates/bevy_animation/src/lib.rs
Comment thread crates/bevy_animation/src/lib.rs Outdated
Comment thread crates/bevy_animation/src/animation_curves.rs
Comment thread crates/bevy_animation/src/lib.rs Outdated
/// with `root_motion_target` set to `None`.
///
/// This happens when root motion is disabled after being active for at least one frame.
pub fn remove_disabled_root_motion(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why this needs to exist. Why can't we just keep the component around with None?

It feels like we should either be adding and removing the component, and store a raw Entity target, or keep the component around using Option with None as a valid state.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea to have the RootMotion component only inserted on entities where the root motion is enabled so it's easier to iterate on them. But I agree that this solution isn't perfect.
I think it's better to remove the root motion configuration (target + mode) from the AnimationPlayer and put it directly inside the RootMotion component. If we want to remove the RootMotion we just have to remove the component.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the end just moved the root motion configuration in a separate component with a hook that removes RootMotion when it's removed. Do you agree with this approach ?

Comment thread examples/animation/root_motion.rs Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Animation Make things move and change over time C-Feature A new feature, making something new possible M-Release-Note Work that should be called out in the blog due to impact S-Needs-Review Needs reviewer attention (from anyone!) to move forward S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged X-Contentious There are nontrivial implications that should be thought through

Projects

Status: Needs SME Triage

Development

Successfully merging this pull request may close these issues.

Enable robust root motion for character animations

6 participants