Crate bevy_sequential_actions
source ·Expand description
§Bevy Sequential Actions
A Bevy library that aims to execute a queue of various actions in a sequential manner. This generally means that one action runs at a time, and when it is done, the next action will start and so on until the queue is empty.
§📜 Getting Started
§Plugin
The quickest way for getting started is adding the SequentialActionsPlugin
to your App
.
use bevy_sequential_actions::*;
fn main() {
App::new()
.add_plugins(SequentialActionsPlugin)
.run();
}
§Modifying Actions
An action is anything that implements the Action
trait,
and can be added to any Entity
that contains the ActionsBundle
.
An entity with actions is referred to as an agent
.
See the ModifyActions
trait for available methods.
fn setup(mut commands: Commands) {
let agent = commands.spawn(ActionsBundle::new()).id();
commands
.actions(agent)
.add(action_a)
.add_many(actions![
action_b,
action_c
])
.order(AddOrder::Front)
.add(action_d)
// ...
}
§Implementing an Action
The Action
trait contains 3 required methods:
is_finished
to determine if an action is finished or not.on_start
which is called when an action is started.on_stop
which is called when an action is stopped.
In addition, there are 3 optional methods:
on_add
which is called when an action is added to the queue.on_remove
which is called when an action is removed from the queue.on_drop
which is the last method to be called with full ownership.
A simple wait action follows.
pub struct WaitAction {
duration: f32, // Seconds
current: Option<f32>, // None
}
impl Action for WaitAction {
fn is_finished(&self, agent: Entity, world: &World) -> bool {
// Determine if wait timer has reached zero.
// By default, this method is called every frame in the Last schedule.
world.get::<WaitTimer>(agent).unwrap().0 <= 0.0
}
fn on_start(&mut self, agent: Entity, world: &mut World) -> bool {
// Take current time (if paused), or use full duration.
let duration = self.current.take().unwrap_or(self.duration);
// Run the wait timer system on the agent.
world.entity_mut(agent).insert(WaitTimer(duration));
// Is action already finished?
// Returning true here will immediately advance the action queue.
self.is_finished(agent, world)
}
fn on_stop(&mut self, agent: Entity, world: &mut World, reason: StopReason) {
// Take the wait timer component from the agent.
let wait_timer = world.entity_mut(agent).take::<WaitTimer>();
// Store current time when paused.
if reason == StopReason::Paused {
self.current = Some(wait_timer.unwrap().0);
}
}
}
#[derive(Component)]
struct WaitTimer(f32);
fn wait_system(mut wait_timer_q: Query<&mut WaitTimer>, time: Res<Time>) {
for mut wait_timer in &mut wait_timer_q {
wait_timer.0 -= time.delta_seconds();
}
}
§⚠️ Warning
One thing to keep in mind is when modifying actions using World
inside the Action
trait.
In order to pass a mutable reference to world when calling the trait methods,
the action has to be temporarily removed from an agent
.
This means that depending on what you do,
the logic for advancing the action queue might not work properly.
In general, there are two rules when modifying actions for an agent
inside the action trait:
- When adding new actions, you should either set the
start
property tofalse
, or push to theActionQueue
component directly. - The
execute
andnext
methods should not be used.
Macros§
- Helper macro for creating an array of boxed actions.
Structs§
- The action queue for an
agent
. - The component bundle that all entities with actions must have.
- Configuration for actions to be added.
- Modify actions using
World
. - Modify actions using
Commands
. - The current action for an
agent
.
Enums§
- The queue order for actions to be added.
- The reason why an
Action
was dropped. - The reason why an
Action
was stopped.
Traits§
- The trait that all actions must implement.
- Proxy method for modifying actions.
- Methods for modifying actions.
Type Aliases§
- A boxed
Action
.