11use std:: f32:: consts:: * ;
2+ use std:: hash:: Hash ;
23
3- use bevy:: { input:: mouse:: MouseMotion , math :: Vec3Swizzles , prelude:: * } ;
4+ use bevy:: { input:: mouse:: MouseMotion , prelude:: * } ;
45use bevy_rapier3d:: prelude:: * ;
56
67/// Manages the FPS controllers. Executes in `PreUpdate`, after bevy's internal
@@ -34,6 +35,7 @@ impl Plugin for FpsControllerPlugin {
3435 PreUpdate ,
3536 (
3637 fps_controller_input,
38+ fps_controller_gamepad_input,
3739 fps_controller_look,
3840 fps_controller_move,
3941 fps_controller_render,
@@ -113,7 +115,7 @@ pub struct FpsController {
113115 pub yaw : f32 ,
114116 pub ground_tick : u8 ,
115117 pub stop_speed : f32 ,
116- pub sensitivity : f32 ,
118+ pub mouse_sensitivity : f32 ,
117119 pub enable_input : bool ,
118120 pub step_offset : f32 ,
119121 pub key_forward : KeyCode ,
@@ -126,6 +128,17 @@ pub struct FpsController {
126128 pub key_jump : KeyCode ,
127129 pub key_fly : KeyCode ,
128130 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 ,
129142}
130143
131144impl Default for FpsController {
@@ -171,7 +184,18 @@ impl Default for FpsController {
171184 key_jump : KeyCode :: Space ,
172185 key_fly : KeyCode :: KeyF ,
173186 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 ,
175199 }
176200 }
177201}
@@ -199,7 +223,7 @@ pub fn fps_controller_input(
199223 for mouse_event in mouse_events. read ( ) {
200224 mouse_delta += mouse_event. delta ;
201225 }
202- mouse_delta *= controller. sensitivity ;
226+ mouse_delta *= controller. mouse_sensitivity ;
203227
204228 input. pitch = ( input. pitch - mouse_delta. y )
205229 . clamp ( -FRAC_PI_2 + ANGLE_EPSILON , FRAC_PI_2 - ANGLE_EPSILON ) ;
@@ -209,9 +233,9 @@ pub fn fps_controller_input(
209233 }
210234
211235 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 ) ,
215239 ) ;
216240 input. sprint = key_input. pressed ( controller. key_sprint ) ;
217241 input. jump = key_input. pressed ( controller. key_jump ) ;
@@ -220,6 +244,51 @@ pub fn fps_controller_input(
220244 }
221245}
222246
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+
223292pub fn fps_controller_look ( mut query : Query < ( & mut FpsController , & FpsControllerInput ) > ) {
224293 for ( mut controller, input) in query. iter_mut ( ) {
225294 controller. pitch = input. pitch ;
@@ -516,16 +585,9 @@ fn acceleration(
516585 wish_direction * acceleration_speed
517586}
518587
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
529591}
530592
531593// ██████╗ ███████╗███╗ ██╗██████╗ ███████╗██████╗
0 commit comments