I've designed a rough (working!) implementation that animates "attachments" in sync with their parent sprite's animation. My specific use case is for customizable clothing, hair, and other accessories for a player sprite.
How the implementation works:
The player is defined a bundle that contains a marker component, spritesheet bundle, and a benimator animation state component.
During the player spawn logic, any attachments (i.e. hair) are spawned using player.with_children(...). Right now, these attachments are only composed of a spritesheet bundle and marker component.
Finally, I have a monolithic animate_player system that does all of the heavy lifting (which I'm hoping can be simplified):
pub fn animate_player(
time: Res<Time>,
animations: Res<Assets<Animation>>,
mut query: Query<
(
&mut AnimationState,
&mut TextureAtlasSprite,
&Movement,
&Handle<Animation>,
),
With<Player>,
>,
mut query_attachments: Query<(&PlayerAttachment, &mut TextureAtlasSprite), Without<Player>>,
) {
for (mut player, mut texture, movement, handle) in &mut query {
if let Some(direction_offset) = &movement.direction.as_ref().map(|dir| dir.to_offset()) {
let animation = match animations.get(handle) {
Some(anim) => anim,
None => continue,
};
player.update(animation, time.delta());
let index = player.frame_index();
texture.index = index + direction_offset * 8;
for (attachment, mut attachment_texture) in &mut query_attachments {
attachment_texture.index = attachment.get_start_index()
+ index
+ direction_offset * attachment.get_row_length());
}
} else {
texture.index = 0;
for (attachment, mut attachment_texture) in &mut query_attachments {
attachment_texture.index = attachment.get_start_index();
}
}
}
}
I feel like this system could be broken up into two systems, one for animating the player and another for the player's attachments. However, I'm unsure of how to structure these two systems: specifically, the synchronization of the animation indexes between parent (player) and children (attachments).
EDIT: I'm not too concerned about the nested iteration, although it immediately sticks out to me when self-reviewing. 99% of the time, only one player will exist in the world, and on the occasion when more than one exists (i.e. customization UI that renders the player in a window), I'd like to have support for those player instances also being animated.