use bevy::prelude::*;
use bevy::scene::prelude::{bsn, CommandsSceneExt};
use bevy_gearbox::prelude::*;
use bevy_gearbox::GearboxPlugin;
#[derive(Message, Clone, Reflect, GearboxMessage)]
struct Crouch {
#[gearbox(target)]
machine: Entity,
}
#[derive(Message, Clone, Reflect, GearboxMessage)]
struct Stand {
#[gearbox(target)]
machine: Entity,
}
#[derive(Message, Clone, Reflect, GearboxMessage)]
struct Draw {
#[gearbox(target)]
machine: Entity,
}
#[derive(Message, Clone, Reflect, GearboxMessage)]
struct Holster {
#[gearbox(target)]
machine: Entity,
}
#[derive(Component)]
struct PostureText;
#[derive(Component)]
struct WeaponText;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(GearboxPlugin::default())
.add_plugins(editor_server)
.add_systems(Startup, setup)
.add_systems(Update, input.before(GearboxSet))
.run();
}
fn setup(mut commands: Commands) {
commands.spawn(Camera2d);
commands.spawn((
Text2d::new("<C> crouch <S> stand <D> draw <H> holster (weapon changes need standing)"),
TextColor(Color::WHITE),
Transform::from_xyz(0.0, 200.0, 0.0),
));
commands.spawn((
PostureText,
Text2d::new(""),
TextColor(Color::srgb(0.6, 0.8, 1.0)),
Transform::from_xyz(0.0, 40.0, 0.0),
));
commands.spawn((
WeaponText,
Text2d::new(""),
TextColor(Color::srgb(1.0, 0.8, 0.6)),
Transform::from_xyz(0.0, -40.0, 0.0),
));
commands.spawn_scene(bsn! {
#Character
StateMachineId("character")
StateMachine
Substates [
#Posture InitialState(#Standing) Substates [
#Standing
on(label::<PostureText>("Posture: Standing"))
Transitions [ (Target(#Crouching) MessageEdge::<Crouch>) ],
#Crouching
on(label::<PostureText>("Posture: Crouching"))
Transitions [ (Target(#Standing) MessageEdge::<Stand>) ],
],
#Weapon InitialState(#Holstered) Substates [
#Holstered
on(label::<WeaponText>("Weapon: Holstered"))
Transitions [ (Target(#Drawn) MessageEdge::<Draw> InState(#Standing)) ],
#Drawn
on(label::<WeaponText>("Weapon: Drawn"))
Transitions [ (Target(#Holstered) MessageEdge::<Holster> InState(#Standing)) ],
],
]
});
}
fn input(
keys: Res<ButtonInput<KeyCode>>,
machine: Single<Entity, With<StateMachine>>,
mut crouch: MessageWriter<Crouch>,
mut stand: MessageWriter<Stand>,
mut draw: MessageWriter<Draw>,
mut holster: MessageWriter<Holster>,
) {
let m = *machine;
if keys.just_pressed(KeyCode::KeyC) {
crouch.write(Crouch { machine: m });
}
if keys.just_pressed(KeyCode::KeyS) {
stand.write(Stand { machine: m });
}
if keys.just_pressed(KeyCode::KeyD) {
draw.write(Draw { machine: m });
}
if keys.just_pressed(KeyCode::KeyH) {
holster.write(Holster { machine: m });
}
}
fn label<L: Component>(text: &'static str) -> impl Fn(On<EnterState>, Single<&mut Text2d, With<L>>) + Clone {
move |_enter, mut label| label.0 = text.into()
}
fn editor_server(app: &mut App) {
#[cfg(feature = "server")]
app.add_plugins(bevy_gearbox::server::ServerPlugin::default());
#[cfg(not(feature = "server"))]
let _ = app;
}