Skip to content

Add bevy_gltf settings for animation player and target creation#22046

Open
greeble-dev wants to merge 7 commits into
bevyengine:mainfrom
greeble-dev:gltf-animation-target-settings
Open

Add bevy_gltf settings for animation player and target creation#22046
greeble-dev wants to merge 7 commits into
bevyengine:mainfrom
greeble-dev:gltf-animation-target-settings

Conversation

@greeble-dev
Copy link
Copy Markdown
Contributor

@greeble-dev greeble-dev commented Dec 6, 2025

Objective

Add support for:

  • Keeping meshes and animations in separate glTFs.
  • Binding meshes to another mesh's animation player.

Background

bevy_animation requires animated entities to have certain components:

  • An AnimationTargetId component that identifies which data in an AnimationClip will apply to the entity.
  • An AnimatedBy component that points to an entity with a AnimationPlayer component.

bevy_gltf automatically sets up these components if the glTF file contains animations. This works well for glTFs that are self-contained meshes with animations. But it fails for two cases:

  1. Separate mesh and animation glTFs.
    • If the mesh glTF doesn't contain any animations then the mesh won't get the components it needs.
  2. Binding a mesh to another mesh's animations.
    • Let's say mesh A wants to play the the same animations as mesh B - so the AnimationPlayer on mesh B will drive both meshes.
    • Mesh A wants the glTF loader to give it AnimationTargetId components so it can bind to the animation clips.
    • But it doesn't want AnimatedBy and AnimationPlayer components created automatically - these will be created separately when binding to mesh B's player.
    • See 🧪 Bone attachments #18262 for an example.

Solution

This PR adds the following settings:

/// Decides if the loader will create [`AnimationTargetId`] components. These
/// are used to identify which parts of an [`AnimationClip`] can be applied to
/// a node.
pub enum GltfCreateAnimationTargetIds {
    /// Never create `AnimationTargetId`s.
    Never,
    /// Always create `AnimationTargetId`s. This is typically used when the glTF
    /// does not contain animations itself, but might be bound to animations in
    /// another glTF or some other source.
    Always,
    /// Only create `AnimationTargetId`s for a hierarchy if at least one node in
    /// the hierarchy is affected by an animation within the glTF.
    #[default]
    Automatically,
}

/// Decides if the loader will create [`AnimationPlayer`] and [`AnimatedBy`]
/// components.
///
/// These components are only created if a hierarchy has [`AnimationTargetId`]
/// components (see [`GltfCreateAnimationTargetIds`]). `AnimationPlayer` components
/// are created on the root node of a hierarchy. `AnimatedBy` components are
/// created on all nodes in a hierarchy, alongside the `AnimationTargetId`
/// components.
pub enum GltfCreateAnimationPlayers {
    /// Never create `AnimationPlayer` and `AnimatedBy` components.
    Never,
    /// Only create `AnimationPlayer` and `AnimatedBy` components if
    /// the hierarchy has `AnimationTargetId` components.
    #[default]
    Automatically,
}

The default values work as before. For the two example cases they would be changed:

  1. Separate mesh and animation glTFs.
    • Set CreateAnimationTargetIds::Always on the mesh, so it always gets IDs even if it doesn't contain animations.
  2. Binding a mesh to another mesh's animation player.
    • Set CreateAnimationTargetIds::Always if necessary, and CreateAnimationPlayers::Never.

The PR also moves the component creation code from load_node to where the scenes are created. This makes the logic a bit simpler, and I think it's nicer if everything is done in one self-contained step rather then being mixed in with other per-node work.

Testing

Tested every combination of settings on a few glTFs with and without animation. Also:

# Check that `bevy_gltf` compiles without `bevy_animation`.
cargo check --no-default-features --features "bevy_gltf"

@greeble-dev greeble-dev added C-Feature A new feature, making something new possible A-Animation Make things move and change over time S-Needs-Review Needs reviewer attention (from anyone!) to move forward A-glTF Related to the glTF 3D scene/model format labels Dec 6, 2025
@greeble-dev greeble-dev changed the title Add bevy_gltf settings that control when animation players and targets are created Add bevy_gltf settings for animation player and target creation Dec 7, 2025
@cart cart added this to Animation Feb 12, 2026
@github-project-automation github-project-automation Bot moved this to Needs SME Triage in Animation Feb 12, 2026
@cart cart closed this May 5, 2026
@github-project-automation github-project-automation Bot moved this from Needs SME Triage to Done in Animation May 5, 2026
@cart cart reopened this May 5, 2026
@github-project-automation github-project-automation Bot moved this from Done to Needs SME Triage in Animation May 5, 2026
Copy link
Copy Markdown
Contributor

@ChristopherBiscardi ChristopherBiscardi left a comment

Choose a reason for hiding this comment

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

This generally seems good and the creation of the target ids as such is a feature that would be useful to have. I think the animation features are a bit complicated and hard to use, but that's not really this PR's responsibility to fix.

Comment thread crates/bevy_gltf/src/loader/mod.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 A-glTF Related to the glTF 3D scene/model format C-Feature A new feature, making something new possible S-Needs-Review Needs reviewer attention (from anyone!) to move forward

Projects

Status: Needs SME Triage

Development

Successfully merging this pull request may close these issues.

3 participants