1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use bevy::prelude::*;
use bevy_input_bindings::prelude::*;
fn main() {
App::new()
.add_plugins((
DefaultPlugins,
// Add the keyboard plugin attached to the custom binder
gamepad::Plugin::<MyActions, MyValues, MyBinding>::new(),
))
// Add observers to print the actions.
.add_observer(|action: On<ActionEvent<MyActions>>, players: Query<&Name, With<Player>>| {
// Iterate over the controlled entities
for controlled_id in action.controlling() {
// Get the player name from the entity stored
let Ok(player_name) = players.get(*controlled_id) else {
continue;
};
// Print data about this action
println!("{} -> {:?}", player_name.as_str(), action.key());
}
})
// Add a startup system to initiate the entities
.add_systems(Startup, |mut commands: Commands| {
commands.spawn(Camera3d::default());
commands.spawn((Player, Name::new("John Doe")));
commands.spawn((Player, Name::new("Emily Williams")));
})
// Add a system to connect the players to newly added gamepads
.add_systems(
Update,
|mut commands: Commands,
uncontrolled_players: Query<
(Entity, &Name),
(With<Player>, Without<ControlledBy>),
>,
added_gamepads: Query<Entity, (Added<MyBinding>, Without<Controlling>)>| {
// Keep track of the players that have already been processed in this iteration
let mut newly_controlled_players = vec![];
// Iterate over added gamepads
for gamepad_id in added_gamepads {
println!("Added gamepad {gamepad_id}");
for (player_id, player_name) in uncontrolled_players {
// Avoid set up two controllers to the same player
if newly_controlled_players.contains(&player_id) {
continue;
}
newly_controlled_players.push(player_id);
// Add the `ControlledBy` component
commands.entity(player_id).insert(ControlledBy(gamepad_id));
// Print the link
println!("{player_name} ({player_id}) is now controlled by {gamepad_id}");
// Leave the loop to avoid setting two players on the same controller
break;
}
}
},
)
.run();
}
#[derive(Component)]
struct Player;
/// Custom actions for this example
#[derive(Debug)]
enum MyActions {
Jump,
}
/// Custom values for this example
#[derive(Debug, Hash, PartialEq, Eq)]
struct MyValues;
/// Custom binder for this example
#[derive(Component, Reflect)]
struct MyBinding {
jump: gamepad::triggers::ButtonPressed,
}
impl Default for MyBinding {
fn default() -> Self {
Self {
jump: gamepad::triggers::ButtonPressed::new(GamepadButton::South),
}
}
}
impl gamepad::Binding<MyActions, MyValues> for MyBinding {
fn get_action_bindings<'a>(
&'a mut self,
) -> Vec<(&'a mut dyn gamepad::TriggerTrait, MyActions)> {
return vec![(&mut self.jump, MyActions::Jump)];
}
}