#Adding tweens on already spawned entities with bevy_tweening

67 messages · Page 1 of 1 (latest)

winter harbor
#

Did anyone have any luck finding out how to do that?
In my case, whenever I add a tween to an already spawned entity, it does not work/animate.
The current way I get around this is by creating a new entity that is a copy of the previous one and inserting the tween to it.

marsh patrol
#

I'have never had issues with that. Spawning a new animator just replaces the old component with a new tween.

winter harbor
marsh patrol
#

how do you tween then?
IIRC only Animator<T> is a component and Tweenable is just data that the animator takes ownership over

#

Or you just meant the entities don't start with a tween/animator?
That should be fine - adding a tween is just inserting an animator.

winter harbor
#

Yeah, I mean the entity does not start with the animator component

#

Weird that it only works if I create a new entity, but doesn't if I add it during runtime

marsh patrol
#

do you have a code snipped of what works vs what doesn't?

winter harbor
#

yeah, I'm going to share it with you when I have a moment!

#
    mut commands: Commands,
    asset_server: ResMut<AssetServer>,
    mut health_entity: Query<(Entity, &mut Health, &mut Sprite, &Transform)>,
) {
    for (entity, health, sprite, transform) in &mut health_entity {
        if health.current_health < 0 {

            let mut tween = alpha_tween(1.0, sprite.color);
            let tween2 = scale_tween(
                    1.0,
                    Vec3::new(1.0, 1.0, 1.0),
                    Vec3::new(2.0, 2.0, 1.0),
                );

            tween.set_completed_event(0);

            commands.entity(entity).despawn();
                commands.spawn_bundle(SpriteBundle {
                    texture: asset_server.load("imgs/dish.png"),
                    transform: Transform::from_xyz(transform.translation.x, transform.translation.y, 0.),
                    ..default()
                })
                .insert(Animator::new(tween))
                .insert(Animator::new(tween2));
        }
    }
}```
#

so this is the code that works

#

where I despawn the previous entity and spawn a new one in its place (perhaps there is a better way to copy its properties to the new one)

#

and the animation plays as expected

#

this however will not work

#
fn health(
    mut commands: Commands,
    asset_server: ResMut<AssetServer>,
    mut health_entity: Query<(Entity, &mut Health, &mut Sprite, &Transform)>,
) {
    for (entity, health, sprite, transform) in &mut health_entity {
        if health.current_health < 0 {

            let mut tween = alpha_tween(1.0, sprite.color);
            let tween2 = scale_tween(
                    1.0,
                    Vec3::new(1.0, 1.0, 1.0),
                    Vec3::new(2.0, 2.0, 1.0),
                );

            tween.set_completed_event(0);

                commands.entity(entity).remove::<Movement>()
                .insert(Animator::new(tween))
                .insert(Animator::new(tween2));
        }
    }
}
#

where I just try to insert the animator components

#

to the queried entity

winter harbor
marsh patrol
#

that insert code looks fine to me

#

I'd try inspecting the entity with smt. like bevy-inspector-egui, if the animator is really not spawned at all

#

dumb question - are you sure the query matches those entities?
Though it looks the same as the snippet above, so it probably does

#

btw. is that bevy main? IIRC don't think 0.8 queries implement IntoIterator

#

Sorry I couldn't help

#

Maybe the crate author can spot smt?
@brazen storm

winter harbor
#

It is bevy main

#

I didn't know the author was around here ^^, maybe!!

marsh patrol
#

would still check with the inspector though - the animator might get inserted, it just might be tweening to smt. else than expected

brazen storm
#

Are you inserting Animator<T> twice on the same entity?!

#

There's only a handful of reason why animation wouldn't work:

  • you use a non-built-in Lens and didn't add the proper animation system; in that case your first example wouldn't work either though
  • you're trying to add Animator<T> twice; I expect Bevy will not let you do that, but who knows... better check with bevy-inspector-egui
#

Otherwise what I do is leave the Animator<T> but re-set its tweenable:

if changed {
    // Animate cursor
    let cursor_tween = Tween::new(
        EaseFunction::QuadraticInOut,
        TweeningType::Once,
        Duration::from_millis(100),
        UiPositionLens {
            start: UiRect {
                left: Val::Px(0.0),
                top: Val::Px(50.0 * old_index as f32),
                ..default()
            },
            end: UiRect {
                left: Val::Px(0.0),
                top: Val::Px(50.0 * cursor.index as f32),
                ..default()
            },
        },
    );
    animator.set_tweenable(cursor_tween);
    animator.rewind();
    animator.state = AnimatorState::Playing;
}
#

Maybe you're missing a rewind() or starting again the playback with state = AnimatorState::Playing (because the animator would have stopped at the end of the previous tween)?

#

Technically I think the rewind() is not needed here but I don't remember for sure.

marsh patrol
winter harbor
#

I used a sprite lens and transform lens

#

the built in ones

#

adding the two animators did work because they are of a different lens type

#

it works when I use them on the first object, for example

#

but I think you're right about the rewind

#

perhaps the animator component I place on an existing entity thinks it has already 'played' the tween

#

due to lifetime

#

time passed

#

or whatever

brazen storm
#

I meant you insert an Animator<Transform> and an Animator<Sprite> each time the system runs

winter harbor
#

maybe I should just implant a paused animator

brazen storm
#

That's unnecessary and probably wrong

winter harbor
#

oh true, that's my bad

brazen storm
#

Keep your animators paused when not in use, and set a new Tween on them when you want to use them

#

(and unpause them)

winter harbor
#

that's what i'll do, thanks djee, pocket cat

#

I think this might solve the issue

brazen storm
#

👍

marsh patrol
#

oh, right, the anim is spawned every frame

brazen storm
winter harbor
#

I don't think the entity is queried twice though, so I don't think it is spawned every frame

#

oh actually it is, because I don't remove the queried

#

component

#

I need to remove that

#

to make it stop

brazen storm
#

yup

winter harbor
#

I removed the wrong one

#

i'll try it next and will let you know

#

and mark the issue as solved

#

that fixed it, removing the health component

#

so that the same entity isn't queried more than one time once it lost its health

#

thanks again, for the help, appreciate it a lot