KirmesBude / bevy_trickfilm

bevy_trickfilm
Apache License 2.0
6 stars 3 forks source link

Asset collection question #19

Closed itstheceo closed 5 months ago

itstheceo commented 5 months ago

Hello! I've just started using the plugin, and it works great (with bevy_asset_loader too)!

I have a question around accessing the animation clips on the AssetCollection, if you could kindly consider the following:

{
    "idle_right": (
        keyframes: KeyframesRange((start: 0, end: 3)),
        duration: 0.8
    ),
    "idle_left": (
        keyframes: KeyframesRange((start: 4, end: 7)),
        duration: 0.8
    ),
    "idle_down": (
        keyframes: KeyframesRange((start: 8, end: 11)),
        duration: 0.8
    ),
    "idle_up": (
        keyframes: KeyframesRange((start: 12, end: 15)),
        duration: 0.8
    ),
}

And then loading via an AssetCollection

#[derive(AssetCollection, Resource)]
pub struct GameAssets {
    #[asset(
        collection(typed),
        paths(
            "player/anim.trickfilm#idle_right",
            "player/anim.trickfilm#idle_left",
            "player/anim.trickfilm#idle_down",
            "player/anim.trickfilm#idle_up"
        )
    )]
    pub player_animations_idle: Vec<Handle<AnimationClip2D>>,
...
}

Currently I access them by index in the Vec as follows (which feels a bit ugly though maybe related to my inexperience with Bevy?):

let animation = match player.state {
        PlayerState::Idling => {
            if player.direction.y < 0.0 {
                assets.player_animations_idle[2].clone_weak()
            } else if player.direction.y > 0.0 {
                assets.player_animations_idle[3].clone_weak()
            } else if player.direction.x < 0.0 {
                assets.player_animations_idle[1].clone_weak()
            } else {
                assets.player_animations_idle[0].clone_weak()
            }
        },
        ...
}

However it would be awesome if I could retrieve them by their names, i.e #idle_right and such! Let me know what you think.

assets.player_animations_idle.get("#idle_right") // or something, to this effect

Cheers.

KirmesBude commented 5 months ago

Thanks for reaching out. Maybe bevy_asset_loader has some way to load it into a hashmap, that I am not sure about. What you can do is just load the whole AnimationClip2DSet, which is a Hashmap of Handle. Then you can do it like this with the downside of having to actually retrieve the AnimationClip2DSet.

#[derive(AssetCollection, Resource)]
pub struct GameAssets {
    #[asset(path = "player/anim.trickfilm")]
    pub player_animations_idle: Handle<AnimationClip2DSet>,
...
}
fn system(
    animation_clip_sets: Res<Assets<AnimationClip2DSet>>,
    ...
) {
    let animation_clip_set = animation_clip_sets.get(assets.player_animations_idle).unwrap(); /* For brevity */
    let animation = match player.state {
            PlayerState::Idling => {
                if player.direction.y < 0.0 {
                    animation_clip_set.get("idle_down")
                } else if player.direction.y > 0.0 {
                    animation_clip_set.get("idle_up")
                } else if player.direction.x < 0.0 {
                    animation_clip_set.get("idle_left")
                } else {
                    animation_clip_set.get("idle_right")
                }
            },
            ...
    }
...
}
itstheceo commented 5 months ago

Ah I see, that's nifty. Thanks for the prompt response!