Comments (7)
I've chosen to use benimator
(at the very least in it's current form) in a game I'm working on. I would be glad to give feedback on any design ideas you come up with regarding switching between animations. Thanks Jonathan
from benimator.
Yeah I dig. Aside from those systems the rest of the code in the repo is agnostic. Worth a look!
I put my code here because I’ve seen this issue linked to in bevy discords more than once so I think it might help people that come here and are wondering about implementing that functionality.
from benimator.
Yeah, definitely, that sounds like a good idea.
Maybe can you share more details about your current use-case? So that I can try thinking about an API.
from benimator.
So imagine you're making a tile-based game. You're gonna be swapping the animations a lot.
- standing still,
idle_down
on repeat - walking left, swap
idle_down
forwalk_left
on repeat - reach destination tile, swap
walk_left
foridle_left
on repeat, etc
In some cases, like an attack, you'll play the attack animation once and then return to the animation you were playing before you attacked.
Here's some musing:
An AnimationChain
and AnimationChainBuilder
let animation_chain = AnimationChainBuilder::new()
.begins_with(attack_animation)
.then(stow_weapon_animation)
.then(idle_animation);
And then that allows you to expand the AnimationChainBuilder to support options other than begins_with
and then
,
and have maybe play_n_times(3, animation)
, then_in_reverse(animation_to_play_backwards)
or more.
Or maybe something like iyes_loopless
where you specify the animation to run given a particular animation state enum value.
let animation_states = AnimationStatesBuilder::new()
.run_in_state(EntityAnimState::IdleDown, idle_down_animation)
.run_in_state(EntityAnimState::WalkLeft, walk_left_animation)
.run_in_state(EntityAnimState::AttackLeft, attack_left_animation);
let animation_state = State::new(EntityAnimState::IdleDown, animation_chain);
animation_state.now(EntityAnimState::WalkLeft); // change animation
animation_state.now(EntityAnimState::AttackLeft).next(EntityAnimState::IdleLeft);
I hope this helps! Let me know if you want to chat about it
from benimator.
Yes, it helps, thanks. I will think more about it and try to come up with an initial design.
from benimator.
Using bevy-simple-state-machine as a reference I was able to implement something that works for benimator
over the weekend
Here's the crux of the code. Also, state_machine.animation_finished()
checks benimator
to see if a Once
animation has finished
pub fn check_animation_transitions(
mut state_machines_query: Query<(Entity, &mut AnimationStateMachine)>,
mut event_writer: EventWriter<TransitionEndedEvent>,
animations: Res<Assets<Animation>>,
) {
for (entity, mut state_machine) in &mut state_machines_query {
if let Some(current_state) = state_machine.current_state() {
if current_state.interruptible || state_machine.animation_finished() {
for transition in state_machine.transitions_from_current_state() {
if transition.trigger.evaluate(&state_machine.variables) {
if let Some(next_state) =
state_machine.get_state(transition.end_state.unwrap())
{
println!("triggering {}", transition);
state_machine.current_state = next_state.name;
// Get new animation and restart benimator with it
let animation = match animations.get(&next_state.base_animation) {
Some(anim) => anim,
None => continue,
};
state_machine.base_frame.reset();
state_machine
.base_frame
.update(animation, Duration::from_millis(0));
// emit event that the transition has completed
event_writer.send(TransitionEndedEvent {
entity,
origin: current_state.state_ref(),
end: transition.end_state,
});
}
}
}
}
}
}
}
pub fn update_animations(
time: Res<Time>,
mut state_machines_query: Query<(&mut AnimationStateMachine, &mut TextureAtlasSprite)>,
animations: Res<Assets<Animation>>,
) {
for (mut state_machine, mut sprite_texture) in &mut state_machines_query {
if let Some(current_state) = state_machine.current_state() {
// Get animation and update it
let animation = match animations.get(¤t_state.base_animation) {
Some(anim) => anim,
None => continue,
};
state_machine.base_frame.update(animation, time.delta());
sprite_texture.index = state_machine.base_frame.frame_index();
}
}
}
from benimator.
Thanks @bmanturner, I'll have to look into this.
Right of the bat, I would like to make sure you're aware that benimator is no longer a bevy plugin. The bevy systems you just shared are still interesting to look at, and it is indeed worthwhile to think about how usage from bevy would look like. I will definitely study what you shared. I just want to make sure you're aware I am looking for an API that is agnostic of bevy.
from benimator.
Related Issues (18)
- Ping Pong mode HOT 1
- feat: Compile-time "Animation" creation HOT 2
- Make the frame list an asset for efficient sharing/reuse of animations
- Play backward HOT 5
- Play Component Should be SparseSet HOT 1
- Prefer using Events to notify end of animations HOT 1
- on demand animation HOT 1
- How to execute logic when the animation reaches a specific frame? HOT 14
- How to switch between animations (not speed, but states like Idle, Running) HOT 1
- Load SpriteSheetAnimation from a file HOT 7
- Dependency Dashboard
- Recommended pattern for resetting to index 0 on pause? HOT 2
- Stabilize: load-from-file HOT 5
- Implement custom playback rates HOT 2
- Allow to define animation FPS HOT 1
- Allow to define animation duration
- Remove `Animation::default()` HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from benimator.