1
1
use std:: f32:: consts:: * ;
2
+ use std:: hash:: Hash ;
2
3
3
- use bevy:: { input:: mouse:: MouseMotion , math :: Vec3Swizzles , prelude:: * } ;
4
+ use bevy:: { input:: mouse:: MouseMotion , prelude:: * } ;
4
5
use bevy_rapier3d:: prelude:: * ;
5
6
6
7
/// Manages the FPS controllers. Executes in `PreUpdate`, after bevy's internal
@@ -34,6 +35,7 @@ impl Plugin for FpsControllerPlugin {
34
35
PreUpdate ,
35
36
(
36
37
fps_controller_input,
38
+ fps_controller_gamepad_input,
37
39
fps_controller_look,
38
40
fps_controller_move,
39
41
fps_controller_render,
@@ -113,7 +115,7 @@ pub struct FpsController {
113
115
pub yaw : f32 ,
114
116
pub ground_tick : u8 ,
115
117
pub stop_speed : f32 ,
116
- pub sensitivity : f32 ,
118
+ pub mouse_sensitivity : f32 ,
117
119
pub enable_input : bool ,
118
120
pub step_offset : f32 ,
119
121
pub key_forward : KeyCode ,
@@ -126,6 +128,17 @@ pub struct FpsController {
126
128
pub key_jump : KeyCode ,
127
129
pub key_fly : KeyCode ,
128
130
pub key_crouch : KeyCode ,
131
+ pub pad_move_x : GamepadAxisType ,
132
+ pub pad_move_y : GamepadAxisType ,
133
+ pub pad_look_x : GamepadAxisType ,
134
+ pub pad_look_y : GamepadAxisType ,
135
+ pub pad_fly_up : GamepadButtonType ,
136
+ pub pad_fly_down : GamepadButtonType ,
137
+ pub pad_jump : GamepadButtonType ,
138
+ pub pad_sprint : GamepadButtonType ,
139
+ pub pad_fly : GamepadButtonType ,
140
+ pub pad_crouch : GamepadButtonType ,
141
+ pub pad_sensitivity : f32 ,
129
142
}
130
143
131
144
impl Default for FpsController {
@@ -171,7 +184,18 @@ impl Default for FpsController {
171
184
key_jump : KeyCode :: Space ,
172
185
key_fly : KeyCode :: KeyF ,
173
186
key_crouch : KeyCode :: ControlLeft ,
174
- sensitivity : 0.001 ,
187
+ mouse_sensitivity : 0.001 ,
188
+ pad_move_x : GamepadAxisType :: LeftStickX ,
189
+ pad_move_y : GamepadAxisType :: LeftStickY ,
190
+ pad_look_x : GamepadAxisType :: RightStickX ,
191
+ pad_look_y : GamepadAxisType :: RightStickY ,
192
+ pad_fly_up : GamepadButtonType :: DPadUp ,
193
+ pad_fly_down : GamepadButtonType :: DPadDown ,
194
+ pad_jump : GamepadButtonType :: South ,
195
+ pad_sprint : GamepadButtonType :: LeftThumb ,
196
+ pad_fly : GamepadButtonType :: RightThumb ,
197
+ pad_crouch : GamepadButtonType :: East ,
198
+ pad_sensitivity : 0.025 ,
175
199
}
176
200
}
177
201
}
@@ -199,7 +223,7 @@ pub fn fps_controller_input(
199
223
for mouse_event in mouse_events. read ( ) {
200
224
mouse_delta += mouse_event. delta ;
201
225
}
202
- mouse_delta *= controller. sensitivity ;
226
+ mouse_delta *= controller. mouse_sensitivity ;
203
227
204
228
input. pitch = ( input. pitch - mouse_delta. y )
205
229
. clamp ( -FRAC_PI_2 + ANGLE_EPSILON , FRAC_PI_2 - ANGLE_EPSILON ) ;
@@ -209,9 +233,9 @@ pub fn fps_controller_input(
209
233
}
210
234
211
235
input. movement = Vec3 :: new (
212
- get_axis ( & key_input, controller. key_right , controller. key_left ) ,
213
- get_axis ( & key_input, controller. key_up , controller. key_down ) ,
214
- get_axis ( & key_input, controller. key_forward , controller. key_back ) ,
236
+ to_axis ( & key_input, controller. key_right , controller. key_left ) ,
237
+ to_axis ( & key_input, controller. key_up , controller. key_down ) ,
238
+ to_axis ( & key_input, controller. key_forward , controller. key_back ) ,
215
239
) ;
216
240
input. sprint = key_input. pressed ( controller. key_sprint ) ;
217
241
input. jump = key_input. pressed ( controller. key_jump ) ;
@@ -220,6 +244,51 @@ pub fn fps_controller_input(
220
244
}
221
245
}
222
246
247
+ pub fn fps_controller_gamepad_input (
248
+ gamepads : Res < Gamepads > ,
249
+ axis_input : Res < Axis < GamepadAxis > > ,
250
+ button_input : Res < ButtonInput < GamepadButton > > ,
251
+ mut query : Query < ( & FpsController , & mut FpsControllerInput ) > ,
252
+ ) {
253
+ for gamepad in gamepads. iter ( ) {
254
+ // Helper functions to get axis and button values
255
+ let axis = |axis_type| {
256
+ axis_input
257
+ . get ( GamepadAxis :: new ( gamepad, axis_type) )
258
+ . unwrap ( )
259
+ } ;
260
+ let button = |button_type| GamepadButton :: new ( gamepad, button_type) ;
261
+
262
+ for ( controller, mut input) in query. iter_mut ( ) {
263
+ if !controller. enable_input {
264
+ continue ;
265
+ }
266
+
267
+ let move_vec = Vec2 :: new ( axis ( controller. pad_move_x ) , axis ( controller. pad_move_y ) ) ;
268
+ let look_vec = Vec2 :: new ( axis ( controller. pad_look_x ) , axis ( controller. pad_look_y ) )
269
+ * controller. pad_sensitivity ;
270
+
271
+ input. pitch = ( input. pitch + look_vec. y )
272
+ . clamp ( -FRAC_PI_2 + ANGLE_EPSILON , FRAC_PI_2 - ANGLE_EPSILON ) ;
273
+ input. yaw -= look_vec. x ;
274
+ if input. yaw . abs ( ) > PI {
275
+ input. yaw = input. yaw . rem_euclid ( TAU ) ;
276
+ }
277
+
278
+ let vertical_axis = to_axis (
279
+ & button_input,
280
+ button ( controller. pad_fly_up ) ,
281
+ button ( controller. pad_fly_down ) ,
282
+ ) ;
283
+ input. movement = Vec3 :: new ( move_vec. x , vertical_axis, move_vec. y ) ;
284
+ input. sprint = button_input. pressed ( button ( controller. pad_sprint ) ) ;
285
+ input. jump = button_input. pressed ( button ( controller. pad_jump ) ) ;
286
+ input. fly = button_input. just_pressed ( button ( controller. pad_fly ) ) ;
287
+ input. crouch = button_input. pressed ( button ( controller. pad_crouch ) ) ;
288
+ }
289
+ }
290
+ }
291
+
223
292
pub fn fps_controller_look ( mut query : Query < ( & mut FpsController , & FpsControllerInput ) > ) {
224
293
for ( mut controller, input) in query. iter_mut ( ) {
225
294
controller. pitch = input. pitch ;
@@ -516,16 +585,9 @@ fn acceleration(
516
585
wish_direction * acceleration_speed
517
586
}
518
587
519
- fn get_pressed ( key_input : & Res < ButtonInput < KeyCode > > , key : KeyCode ) -> f32 {
520
- if key_input. pressed ( key) {
521
- 1.0
522
- } else {
523
- 0.0
524
- }
525
- }
526
-
527
- fn get_axis ( key_input : & Res < ButtonInput < KeyCode > > , key_pos : KeyCode , key_neg : KeyCode ) -> f32 {
528
- get_pressed ( key_input, key_pos) - get_pressed ( key_input, key_neg)
588
+ /// Converts two button inputs into an f32 with a range of [-1, 1]
589
+ fn to_axis < T : Copy + Eq + Send + Sync + Hash > ( input : & Res < ButtonInput < T > > , pos : T , neg : T ) -> f32 {
590
+ input. pressed ( pos) as u8 as f32 - input. pressed ( neg) as u8 as f32
529
591
}
530
592
531
593
// ██████╗ ███████╗███╗ ██╗██████╗ ███████╗██████╗
0 commit comments