#Adding tweens on already spawned entities with bevy_tweening
67 messages · Page 1 of 1 (latest)
I'have never had issues with that. Spawning a new animator just replaces the old component with a new tween.
Oh, I don't actually spawn them with the animator component at first, I just add it later, when I need an animation (They spawn without an animation)
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.
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
do you have a code snipped of what works vs what doesn't?
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
what do you think might be causing this?
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
Thanks for trying, it does match the entities because the 'Movement' component is successfully removed and when I do the workaround, the entity queried is correctly destroyed
It is bevy main
I didn't know the author was around here ^^, maybe!!
would still check with the inspector though - the animator might get inserted, it just might be tweening to smt. else than expected
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.
Seemingly one is a Transform tween and the other a Sprite tween, so those animate different components and 2 animators make sense there, right?
Yeah lol, I tried to do tracks for this, but it kept telling me I couldn't insert two tracks of different types, or perhaps I didn't understand the debugger well enough
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
I meant you insert an Animator<Transform> and an Animator<Sprite> each time the system runs
maybe I should just implant a paused animator
That's unnecessary and probably wrong
oh true, that's my bad
Keep your animators paused when not in use, and set a new Tween on them when you want to use them
(and unpause them)
👍
oh, right, the anim is spawned every frame
Tween<Transform> and an Tween<Sprite> are different types. You can't mix them into a same Tracks<T> (because what would T be?!)
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
yup