Skip to content

Conversation

greeble-dev
Copy link
Contributor

@greeble-dev greeble-dev commented Aug 27, 2025

Objective

Add flexibility by refactoring AnimationTarget into two separate components. This will smooth the path for future animation features.

Background

bevy_animation animates entities by assigning them AnimationTarget components:

struct AnimationTarget {
    player: Entity,
    id: AnimationTargetId,
}
  • player: Entity links to an entity that contains an AnimationPlayer component. An AnimationPlayer plays AnimationClip assets.
  • id: AnimationTargetId identifies which tracks in an AnimationClip apply to the target entity.

When loading a glTF these components are automatically created. They can also be created manually.

Problem

The two parts of AnimationTarget often go together but sometimes would be better separated:

  1. I might want to calculate the AnimationTargetId first, but not link it up to an AnimationPlayer until later (see 🧪 Bone attachments #18262 for an example).
  2. I might want to use AnimationTargetId but not use AnimationPlayer - maybe I've got a different component that plays AnimationClips.

In theory player could be left as Entity::PLACEHOLDER, but that's messy and will trigger a warning in animate_targets.

Solution

This PR splits AnimationTarget into two components:

  1. AnimationTargetId is just the original struct with a component derive.
  2. AnimationPlayerTarget is a new unit struct (Entity).

I'm not convinced AnimationPlayerTarget is a good name, but it does fit the usual source/target naming for entity relationships. AnimationPlayerRef was another candidate.

AnimationPlayerTarget could be a relationship target, but there would be a performance cost from making AnimationPlayer a relationship source. Maybe it's still a good idea, but that's probably best left to another PR.

Performance

Profiled on many_foxes - difference was negligible.

Testing

Examples animated_mesh, animated_transform, animated_ui, animation_masks, eased_motion, scene_viewer.

Future

If this PR lands then I'll probably file a follow up that adds more flexibility to the the glTF loader creation of AnimationTargetId and AnimationPlayer. This will help #18262 and enable some other features.

@greeble-dev greeble-dev added C-Feature A new feature, making something new possible A-Animation Make things move and change over time D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Aug 27, 2025
@greeble-dev greeble-dev added the M-Needs-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide label Aug 27, 2025
@viridia
Copy link
Contributor

viridia commented Aug 27, 2025

How about AnimationPlayerRef or AnimationPlayerId?

@greeble-dev
Copy link
Contributor Author

How about AnimationPlayerRef or AnimationPlayerId?

AnimationPlayerRef makes sense to me, but I suspect it might get pushback as the relationship system tends to use "target".

AnimationPlayerId I'm not so keen on - I read "SomethingId" as "this component identifies the entity it's contained in".

@viridia
Copy link
Contributor

viridia commented Aug 27, 2025

The name "target" is used at a meta-level: no relation components have the name "target" in them.

Some alternative names:

  • ActivePlayer
  • ActiveAnimationPlayer
  • AnimatedBy

@greeble-dev
Copy link
Contributor Author

AnimatedBy does seem the most relationship-y. The one wrinkle is whether it's polymorphic - does it link to an entity which can have any kind of animation driver component? Or does it link specifically to an entity with an AnimationPlayer component? If it's the former then seems fine. If it's the latter (which is the current situation) then it feels a bit imprecise.

I guess AnimatedByAnimationPlayer is a precise but ugly option.

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 D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes M-Needs-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide S-Needs-Review Needs reviewer attention (from anyone!) to move forward
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants