From bd59ae5c2c9b4d606511dff04e80671955c3ddfa Mon Sep 17 00:00:00 2001 From: Tomato <67799071+100-TomatoJuice@users.noreply.github.com> Date: Mon, 28 Aug 2023 17:59:06 -0700 Subject: [PATCH 01/13] Add sensitivity --- src/axislike.rs | 23 +++++++++++++++++++++++ src/input_streams.rs | 4 ++-- src/lib.rs | 2 +- tests/gamepad_axis.rs | 9 +++++++++ tests/mouse_motion.rs | 9 +++++++++ tests/mouse_wheel.rs | 9 +++++++++ 6 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/axislike.rs b/src/axislike.rs index 88004553..5b78cf4d 100644 --- a/src/axislike.rs +++ b/src/axislike.rs @@ -30,6 +30,8 @@ pub struct SingleAxis { pub negative_low: f32, /// Whether to invert output values from this axis. pub inverted: bool, + + pub sensitivity: f32, /// The target value for this input, used for input mocking. /// /// WARNING: this field is ignored for the sake of [`Eq`] and [`Hash`](std::hash::Hash) @@ -45,6 +47,7 @@ impl SingleAxis { positive_low: threshold, negative_low: -threshold, inverted: false, + sensitivity: 1.0, value: None, } } @@ -60,6 +63,7 @@ impl SingleAxis { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, value: Some(value), } } @@ -72,6 +76,7 @@ impl SingleAxis { positive_low: 0., negative_low: 0., inverted: false, + sensitivity: 1.0, value: None, } } @@ -84,6 +89,7 @@ impl SingleAxis { positive_low: 0., negative_low: 0., inverted: false, + sensitivity: 1.0, value: None, } } @@ -96,6 +102,7 @@ impl SingleAxis { positive_low: 0., negative_low: 0., inverted: false, + sensitivity: 1.0, value: None, } } @@ -108,6 +115,7 @@ impl SingleAxis { positive_low: 0., negative_low: 0., inverted: false, + sensitivity: 1.0, value: None, } } @@ -121,6 +129,7 @@ impl SingleAxis { negative_low: threshold, positive_low: f32::MAX, inverted: false, + sensitivity: 1.0, value: None, } } @@ -134,6 +143,7 @@ impl SingleAxis { negative_low: f32::MIN, positive_low: threshold, inverted: false, + sensitivity: 1.0, value: None, } } @@ -146,6 +156,12 @@ impl SingleAxis { self } + #[must_use] + pub fn with_sensitivity(mut self, sensitivity: f32) -> SingleAxis{ + self.sensitivity = sensitivity; + self + } + /// Returns this [`SingleAxis`] inverted. #[must_use] pub fn inverted(mut self) -> Self { @@ -281,6 +297,13 @@ impl DualAxis { self } + #[must_use] + pub fn with_sensitivity(mut self, x_sensitivity: f32, y_sensitivity: f32) -> DualAxis{ + self.x.sensitivity = x_sensitivity; + self.y.sensitivity = y_sensitivity; + self + } + /// Returns this [`DualAxis`] with an inverted X-axis. #[must_use] pub fn inverted_x(mut self) -> DualAxis { diff --git a/src/input_streams.rs b/src/input_streams.rs index 51e276a4..f557dd72 100644 --- a/src/input_streams.rs +++ b/src/input_streams.rs @@ -266,9 +266,9 @@ impl<'a> InputStreams<'a> { if value >= axis.negative_low && value <= axis.positive_low && include_deadzone { 0.0 } else if axis.inverted { - -value + -value * axis.sensitivity } else { - value + value * axis.sensitivity } }; diff --git a/src/lib.rs b/src/lib.rs index ed500e20..24669ccd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -#![forbid(missing_docs)] +//#![forbid(missing_docs)] #![forbid(unsafe_code)] #![warn(clippy::doc_markdown)] #![doc = include_str!("../README.md")] diff --git a/tests/gamepad_axis.rs b/tests/gamepad_axis.rs index c08f14de..53adff90 100644 --- a/tests/gamepad_axis.rs +++ b/tests/gamepad_axis.rs @@ -79,6 +79,7 @@ fn game_pad_single_axis_mocking() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, + sensitivity: 1.0, inverted: false, }; @@ -99,6 +100,7 @@ fn game_pad_dual_axis_mocking() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, + sensitivity: 1.0, inverted: false, }, y: SingleAxis { @@ -106,6 +108,7 @@ fn game_pad_dual_axis_mocking() { value: Some(0.), positive_low: 0.0, negative_low: 0.0, + sensitivity: 1.0, inverted: false, }, deadzone: DualAxis::DEFAULT_DEADZONE_SHAPE, @@ -137,6 +140,7 @@ fn game_pad_single_axis() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }; app.send_input(input); app.update(); @@ -150,6 +154,7 @@ fn game_pad_single_axis() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }; app.send_input(input); app.update(); @@ -163,6 +168,7 @@ fn game_pad_single_axis() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }; app.send_input(input); app.update(); @@ -176,6 +182,7 @@ fn game_pad_single_axis() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }; app.send_input(input); app.update(); @@ -190,6 +197,7 @@ fn game_pad_single_axis() { positive_low: 0.1, negative_low: 0.1, inverted: false, + sensitivity: 1.0, }; app.send_input(input); app.update(); @@ -203,6 +211,7 @@ fn game_pad_single_axis() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }; app.send_input(input); app.update(); diff --git a/tests/mouse_motion.rs b/tests/mouse_motion.rs index 9a5ccc51..fd8a575b 100644 --- a/tests/mouse_motion.rs +++ b/tests/mouse_motion.rs @@ -75,6 +75,7 @@ fn mouse_motion_single_axis_mocking() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }; app.send_input(input); @@ -95,6 +96,7 @@ fn mouse_motion_dual_axis_mocking() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }, y: SingleAxis { axis_type: AxisType::MouseMotion(MouseMotionAxisType::Y), @@ -102,6 +104,7 @@ fn mouse_motion_dual_axis_mocking() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }, deadzone: DualAxis::DEFAULT_DEADZONE_SHAPE, }; @@ -171,6 +174,7 @@ fn mouse_motion_single_axis() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }; app.send_input(input); app.update(); @@ -184,6 +188,7 @@ fn mouse_motion_single_axis() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }; app.send_input(input); app.update(); @@ -197,6 +202,7 @@ fn mouse_motion_single_axis() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }; app.send_input(input); app.update(); @@ -210,6 +216,7 @@ fn mouse_motion_single_axis() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }; app.send_input(input); app.update(); @@ -224,6 +231,7 @@ fn mouse_motion_single_axis() { positive_low: 0.1, negative_low: 0.1, inverted: false, + sensitivity: 1.0, }; app.send_input(input); app.update(); @@ -237,6 +245,7 @@ fn mouse_motion_single_axis() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }; app.send_input(input); app.update(); diff --git a/tests/mouse_wheel.rs b/tests/mouse_wheel.rs index e43aa568..72f46fcf 100644 --- a/tests/mouse_wheel.rs +++ b/tests/mouse_wheel.rs @@ -76,6 +76,7 @@ fn mouse_wheel_single_axis_mocking() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }; app.send_input(input); @@ -96,6 +97,7 @@ fn mouse_wheel_dual_axis_mocking() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }, y: SingleAxis { axis_type: AxisType::MouseWheel(MouseWheelAxisType::Y), @@ -103,6 +105,7 @@ fn mouse_wheel_dual_axis_mocking() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }, deadzone: DualAxis::DEFAULT_DEADZONE_SHAPE, }; @@ -172,6 +175,7 @@ fn mouse_wheel_single_axis() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }; app.send_input(input); app.update(); @@ -185,6 +189,7 @@ fn mouse_wheel_single_axis() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }; app.send_input(input); app.update(); @@ -198,6 +203,7 @@ fn mouse_wheel_single_axis() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }; app.send_input(input); app.update(); @@ -211,6 +217,7 @@ fn mouse_wheel_single_axis() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }; app.send_input(input); app.update(); @@ -225,6 +232,7 @@ fn mouse_wheel_single_axis() { positive_low: 0.1, negative_low: 0.1, inverted: false, + sensitivity: 1.0, }; app.send_input(input); app.update(); @@ -238,6 +246,7 @@ fn mouse_wheel_single_axis() { positive_low: 0.0, negative_low: 0.0, inverted: false, + sensitivity: 1.0, }; app.send_input(input); app.update(); From c117c1c8a8056879f54d24e01e39aee783440ea7 Mon Sep 17 00:00:00 2001 From: Tomato <67799071+100-TomatoJuice@users.noreply.github.com> Date: Tue, 29 Aug 2023 18:54:32 -0700 Subject: [PATCH 02/13] Update `Hash` and `Eq` for `SingleAxis` --- src/axislike.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/axislike.rs b/src/axislike.rs index 5b78cf4d..cba75f37 100644 --- a/src/axislike.rs +++ b/src/axislike.rs @@ -175,6 +175,7 @@ impl PartialEq for SingleAxis { self.axis_type == other.axis_type && FloatOrd(self.positive_low) == FloatOrd(other.positive_low) && FloatOrd(self.negative_low) == FloatOrd(other.negative_low) + && FloatOrd(self.sensitivity) == FloatOrd(other.sensitivity) } } impl Eq for SingleAxis {} @@ -183,6 +184,7 @@ impl std::hash::Hash for SingleAxis { self.axis_type.hash(state); FloatOrd(self.positive_low).hash(state); FloatOrd(self.negative_low).hash(state); + FloatOrd(self.sensitivity).hash(state); } } From cc280863095bd9fb11704c2d891c4fa1e778ebd2 Mon Sep 17 00:00:00 2001 From: Tomato <67799071+100-TomatoJuice@users.noreply.github.com> Date: Wed, 30 Aug 2023 15:19:38 -0700 Subject: [PATCH 03/13] Merged `inverted` into `sensitivity` --- src/axislike.rs | 12 +----------- src/input_streams.rs | 5 ++--- tests/gamepad_axis.rs | 9 --------- tests/mouse_motion.rs | 9 --------- tests/mouse_wheel.rs | 9 --------- 5 files changed, 3 insertions(+), 41 deletions(-) diff --git a/src/axislike.rs b/src/axislike.rs index cba75f37..0f19c9df 100644 --- a/src/axislike.rs +++ b/src/axislike.rs @@ -28,8 +28,6 @@ pub struct SingleAxis { pub positive_low: f32, /// Any axis value lower than this will trigger the input. pub negative_low: f32, - /// Whether to invert output values from this axis. - pub inverted: bool, pub sensitivity: f32, /// The target value for this input, used for input mocking. @@ -46,7 +44,6 @@ impl SingleAxis { axis_type: axis_type.into(), positive_low: threshold, negative_low: -threshold, - inverted: false, sensitivity: 1.0, value: None, } @@ -62,7 +59,6 @@ impl SingleAxis { axis_type: axis_type.into(), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, value: Some(value), } @@ -75,7 +71,6 @@ impl SingleAxis { axis_type: AxisType::MouseWheel(MouseWheelAxisType::X), positive_low: 0., negative_low: 0., - inverted: false, sensitivity: 1.0, value: None, } @@ -88,7 +83,6 @@ impl SingleAxis { axis_type: AxisType::MouseWheel(MouseWheelAxisType::Y), positive_low: 0., negative_low: 0., - inverted: false, sensitivity: 1.0, value: None, } @@ -101,7 +95,6 @@ impl SingleAxis { axis_type: AxisType::MouseMotion(MouseMotionAxisType::X), positive_low: 0., negative_low: 0., - inverted: false, sensitivity: 1.0, value: None, } @@ -114,7 +107,6 @@ impl SingleAxis { axis_type: AxisType::MouseMotion(MouseMotionAxisType::Y), positive_low: 0., negative_low: 0., - inverted: false, sensitivity: 1.0, value: None, } @@ -128,7 +120,6 @@ impl SingleAxis { axis_type: axis_type.into(), negative_low: threshold, positive_low: f32::MAX, - inverted: false, sensitivity: 1.0, value: None, } @@ -142,7 +133,6 @@ impl SingleAxis { axis_type: axis_type.into(), negative_low: f32::MIN, positive_low: threshold, - inverted: false, sensitivity: 1.0, value: None, } @@ -165,7 +155,7 @@ impl SingleAxis { /// Returns this [`SingleAxis`] inverted. #[must_use] pub fn inverted(mut self) -> Self { - self.inverted = !self.inverted; + self.sensitivity = -self.sensitivity; self } } diff --git a/src/input_streams.rs b/src/input_streams.rs index f557dd72..919ccdf0 100644 --- a/src/input_streams.rs +++ b/src/input_streams.rs @@ -265,9 +265,8 @@ impl<'a> InputStreams<'a> { let value_in_axis_range = |axis: &SingleAxis, value: f32| -> f32 { if value >= axis.negative_low && value <= axis.positive_low && include_deadzone { 0.0 - } else if axis.inverted { - -value * axis.sensitivity - } else { + } + else { value * axis.sensitivity } }; diff --git a/tests/gamepad_axis.rs b/tests/gamepad_axis.rs index 53adff90..6b580a76 100644 --- a/tests/gamepad_axis.rs +++ b/tests/gamepad_axis.rs @@ -80,7 +80,6 @@ fn game_pad_single_axis_mocking() { positive_low: 0.0, negative_low: 0.0, sensitivity: 1.0, - inverted: false, }; app.send_input(input); @@ -101,7 +100,6 @@ fn game_pad_dual_axis_mocking() { positive_low: 0.0, negative_low: 0.0, sensitivity: 1.0, - inverted: false, }, y: SingleAxis { axis_type: AxisType::Gamepad(GamepadAxisType::LeftStickY), @@ -109,7 +107,6 @@ fn game_pad_dual_axis_mocking() { positive_low: 0.0, negative_low: 0.0, sensitivity: 1.0, - inverted: false, }, deadzone: DualAxis::DEFAULT_DEADZONE_SHAPE, }; @@ -139,7 +136,6 @@ fn game_pad_single_axis() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -153,7 +149,6 @@ fn game_pad_single_axis() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -167,7 +162,6 @@ fn game_pad_single_axis() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -181,7 +175,6 @@ fn game_pad_single_axis() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -196,7 +189,6 @@ fn game_pad_single_axis() { // Usually a small deadzone threshold will be set positive_low: 0.1, negative_low: 0.1, - inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -210,7 +202,6 @@ fn game_pad_single_axis() { value: None, positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }; app.send_input(input); diff --git a/tests/mouse_motion.rs b/tests/mouse_motion.rs index fd8a575b..99564e98 100644 --- a/tests/mouse_motion.rs +++ b/tests/mouse_motion.rs @@ -74,7 +74,6 @@ fn mouse_motion_single_axis_mocking() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }; @@ -95,7 +94,6 @@ fn mouse_motion_dual_axis_mocking() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }, y: SingleAxis { @@ -103,7 +101,6 @@ fn mouse_motion_dual_axis_mocking() { value: Some(0.), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }, deadzone: DualAxis::DEFAULT_DEADZONE_SHAPE, @@ -173,7 +170,6 @@ fn mouse_motion_single_axis() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -187,7 +183,6 @@ fn mouse_motion_single_axis() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -201,7 +196,6 @@ fn mouse_motion_single_axis() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -215,7 +209,6 @@ fn mouse_motion_single_axis() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -230,7 +223,6 @@ fn mouse_motion_single_axis() { // Usually a small deadzone threshold will be set positive_low: 0.1, negative_low: 0.1, - inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -244,7 +236,6 @@ fn mouse_motion_single_axis() { value: None, positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }; app.send_input(input); diff --git a/tests/mouse_wheel.rs b/tests/mouse_wheel.rs index 72f46fcf..470e3d9b 100644 --- a/tests/mouse_wheel.rs +++ b/tests/mouse_wheel.rs @@ -75,7 +75,6 @@ fn mouse_wheel_single_axis_mocking() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }; @@ -96,7 +95,6 @@ fn mouse_wheel_dual_axis_mocking() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }, y: SingleAxis { @@ -104,7 +102,6 @@ fn mouse_wheel_dual_axis_mocking() { value: Some(0.), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }, deadzone: DualAxis::DEFAULT_DEADZONE_SHAPE, @@ -174,7 +171,6 @@ fn mouse_wheel_single_axis() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -188,7 +184,6 @@ fn mouse_wheel_single_axis() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -202,7 +197,6 @@ fn mouse_wheel_single_axis() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -216,7 +210,6 @@ fn mouse_wheel_single_axis() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -231,7 +224,6 @@ fn mouse_wheel_single_axis() { // Usually a small deadzone threshold will be set positive_low: 0.1, negative_low: 0.1, - inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -245,7 +237,6 @@ fn mouse_wheel_single_axis() { value: None, positive_low: 0.0, negative_low: 0.0, - inverted: false, sensitivity: 1.0, }; app.send_input(input); From 48442e8845b5009b2a74e83da4e081c6798c5aa4 Mon Sep 17 00:00:00 2001 From: Tomato <67799071+100-TomatoJuice@users.noreply.github.com> Date: Wed, 30 Aug 2023 17:35:48 -0700 Subject: [PATCH 04/13] Add test --- src/input_streams.rs | 3 +- tests/gamepad_axis.rs | 71 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/input_streams.rs b/src/input_streams.rs index 919ccdf0..0632019c 100644 --- a/src/input_streams.rs +++ b/src/input_streams.rs @@ -265,8 +265,7 @@ impl<'a> InputStreams<'a> { let value_in_axis_range = |axis: &SingleAxis, value: f32| -> f32 { if value >= axis.negative_low && value <= axis.positive_low && include_deadzone { 0.0 - } - else { + } else { value * axis.sensitivity } }; diff --git a/tests/gamepad_axis.rs b/tests/gamepad_axis.rs index 6b580a76..0faca0a0 100644 --- a/tests/gamepad_axis.rs +++ b/tests/gamepad_axis.rs @@ -210,6 +210,77 @@ fn game_pad_single_axis() { assert!(!action_state.pressed(AxislikeTestAction::Y)); } +#[test] +fn game_pad_single_axis_inverted() { + let mut app = test_app(); + app.insert_resource(InputMap::new([ + ( + SingleAxis::symmetric(GamepadAxisType::LeftStickX, 0.1).inverted(), + AxislikeTestAction::X, + ), + ( + SingleAxis::symmetric(GamepadAxisType::LeftStickY, 0.1).inverted(), + AxislikeTestAction::Y, + ), + ])); + + // +X + let input = SingleAxis { + axis_type: AxisType::Gamepad(GamepadAxisType::LeftStickX), + value: Some(1.), + positive_low: 0.0, + negative_low: 0.0, + sensitivity: -1.0, + }.inverted(); + app.send_input(input); + app.update(); + let action_state = app.world.resource::>(); + assert!(action_state.pressed(AxislikeTestAction::X)); + assert!(action_state.value(AxislikeTestAction::X) == -1.0); + + // -X + let input = SingleAxis { + axis_type: AxisType::Gamepad(GamepadAxisType::LeftStickX), + value: Some(-1.), + positive_low: 0.0, + negative_low: 0.0, + sensitivity: -1.0, + }; + app.send_input(input); + app.update(); + let action_state = app.world.resource::>(); + assert!(action_state.pressed(AxislikeTestAction::X)); + assert!(action_state.value(AxislikeTestAction::X) == 1.0); + + // +Y + let input = SingleAxis { + axis_type: AxisType::Gamepad(GamepadAxisType::LeftStickY), + value: Some(1.), + positive_low: 0.0, + negative_low: 0.0, + sensitivity: -1.0, + }; + app.send_input(input); + app.update(); + let action_state = app.world.resource::>(); + assert!(action_state.pressed(AxislikeTestAction::Y)); + assert!(action_state.value(AxislikeTestAction::Y) == -1.0); + + // -Y + let input = SingleAxis { + axis_type: AxisType::Gamepad(GamepadAxisType::LeftStickY), + value: Some(-1.), + positive_low: 0.0, + negative_low: 0.0, + sensitivity: -1.0, + }; + app.send_input(input); + app.update(); + let action_state = app.world.resource::>(); + assert!(action_state.pressed(AxislikeTestAction::Y)); + assert!(action_state.value(AxislikeTestAction::Y) == 1.0); +} + #[test] fn game_pad_dual_axis_cross() { let mut app = test_app(); From 51bc0095f08f0be661ea304085e83ad63b305906 Mon Sep 17 00:00:00 2001 From: Tomato <67799071+100-TomatoJuice@users.noreply.github.com> Date: Wed, 30 Aug 2023 17:50:54 -0700 Subject: [PATCH 05/13] Add docs --- src/axislike.rs | 7 ++++++- src/lib.rs | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/axislike.rs b/src/axislike.rs index 0f19c9df..a23f091c 100644 --- a/src/axislike.rs +++ b/src/axislike.rs @@ -28,7 +28,10 @@ pub struct SingleAxis { pub positive_low: f32, /// Any axis value lower than this will trigger the input. pub negative_low: f32, - + /// How sensitive the axis is to input values. + /// + /// Since sensitivity is a multiplier, any value `>1.0` will increase sensitivity while any value `<1.0` will decrease sensitivity. + /// Negative values will invert the axis. pub sensitivity: f32, /// The target value for this input, used for input mocking. /// @@ -146,6 +149,7 @@ impl SingleAxis { self } + /// Returns this [`SingleAxis`] with the sensitivity set to the specified value #[must_use] pub fn with_sensitivity(mut self, sensitivity: f32) -> SingleAxis{ self.sensitivity = sensitivity; @@ -289,6 +293,7 @@ impl DualAxis { self } + /// Returns this [`DualAxis`] with the sensitivity set to the specified values #[must_use] pub fn with_sensitivity(mut self, x_sensitivity: f32, y_sensitivity: f32) -> DualAxis{ self.x.sensitivity = x_sensitivity; diff --git a/src/lib.rs b/src/lib.rs index 24669ccd..ed500e20 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -//#![forbid(missing_docs)] +#![forbid(missing_docs)] #![forbid(unsafe_code)] #![warn(clippy::doc_markdown)] #![doc = include_str!("../README.md")] From 58cd442d10bce1ad90d5a8de2d4fd42744a43387 Mon Sep 17 00:00:00 2001 From: Tomato <67799071+100-TomatoJuice@users.noreply.github.com> Date: Wed, 30 Aug 2023 17:55:20 -0700 Subject: [PATCH 06/13] Update RELEASES.md --- RELEASES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASES.md b/RELEASES.md index d844f9bc..8ec3b9fb 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -12,6 +12,7 @@ ### Enhancements - Added `DeadZoneShape` for `DualAxis` which allows for different deadzones shapes: cross, rectangle, and ellipse. +- Added sensitivity for `SingleAxis` and `DualAxis`. ## Version 0.10 From 9da8266f3f4111698932881f2806afc938bc2461 Mon Sep 17 00:00:00 2001 From: Tomato <67799071+100-TomatoJuice@users.noreply.github.com> Date: Wed, 30 Aug 2023 17:55:38 -0700 Subject: [PATCH 07/13] cargo fmt --- src/axislike.rs | 6 +++--- tests/gamepad_axis.rs | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/axislike.rs b/src/axislike.rs index a23f091c..fe6bff15 100644 --- a/src/axislike.rs +++ b/src/axislike.rs @@ -29,7 +29,7 @@ pub struct SingleAxis { /// Any axis value lower than this will trigger the input. pub negative_low: f32, /// How sensitive the axis is to input values. - /// + /// /// Since sensitivity is a multiplier, any value `>1.0` will increase sensitivity while any value `<1.0` will decrease sensitivity. /// Negative values will invert the axis. pub sensitivity: f32, @@ -151,7 +151,7 @@ impl SingleAxis { /// Returns this [`SingleAxis`] with the sensitivity set to the specified value #[must_use] - pub fn with_sensitivity(mut self, sensitivity: f32) -> SingleAxis{ + pub fn with_sensitivity(mut self, sensitivity: f32) -> SingleAxis { self.sensitivity = sensitivity; self } @@ -295,7 +295,7 @@ impl DualAxis { /// Returns this [`DualAxis`] with the sensitivity set to the specified values #[must_use] - pub fn with_sensitivity(mut self, x_sensitivity: f32, y_sensitivity: f32) -> DualAxis{ + pub fn with_sensitivity(mut self, x_sensitivity: f32, y_sensitivity: f32) -> DualAxis { self.x.sensitivity = x_sensitivity; self.y.sensitivity = y_sensitivity; self diff --git a/tests/gamepad_axis.rs b/tests/gamepad_axis.rs index 0faca0a0..cbf31052 100644 --- a/tests/gamepad_axis.rs +++ b/tests/gamepad_axis.rs @@ -231,7 +231,8 @@ fn game_pad_single_axis_inverted() { positive_low: 0.0, negative_low: 0.0, sensitivity: -1.0, - }.inverted(); + } + .inverted(); app.send_input(input); app.update(); let action_state = app.world.resource::>(); From eb2403995d7fc63780a3de7c5865e9e46953f27c Mon Sep 17 00:00:00 2001 From: Tomato <67799071+100-TomatoJuice@users.noreply.github.com> Date: Wed, 30 Aug 2023 18:57:02 -0700 Subject: [PATCH 08/13] Add `get_mut()` to `InputMap` --- src/input_map.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/input_map.rs b/src/input_map.rs index 862235ff..e3d25421 100644 --- a/src/input_map.rs +++ b/src/input_map.rs @@ -425,6 +425,12 @@ impl InputMap { &self.map[action.index()] } + /// Returns the `action` mappings + #[must_use] + pub fn get_mut(&mut self, action: A) -> &mut PetitSet { + &mut self.map[action.index()] + } + /// How many input bindings are registered total? #[must_use] pub fn len(&self) -> usize { From a1bb6364733974832ef8c387c746d6f400ffec29 Mon Sep 17 00:00:00 2001 From: Tomato <67799071+100-TomatoJuice@users.noreply.github.com> Date: Wed, 30 Aug 2023 19:07:43 -0700 Subject: [PATCH 09/13] Add test doc for changing values --- src/input_map.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/input_map.rs b/src/input_map.rs index e3d25421..7cdfdf0b 100644 --- a/src/input_map.rs +++ b/src/input_map.rs @@ -73,6 +73,44 @@ use std::marker::PhantomData; /// // Removal /// input_map.clear_action(Action::Hide); ///``` +/// +/// # Example +/// ```rust +/// use bevy::prelude::*; +/// use leafwing_input_manager::prelude::*; +/// use leafwing_input_manager::user_input::InputKind; +/// +/// #[derive(Actionlike, PartialEq, Eq, Clone, Copy, Hash, Debug, Reflect)] +/// enum Action { +/// Look, +/// } +/// +/// fn spawn_player(mut commands: Commands){ +/// commands.spawn(InputManagerBundle:: { +/// action_state: ActionState::default(), +/// input_map: InputMap::default() +/// .insert(DualAxis::left_stick().with_sensitivity(1.0, 1.0), Action::Look) +/// .insert(DualAxis::mouse_motion().with_sensitivity(1.0, 1.0), Action::Look) +/// .build(), +/// }); +/// } +/// +/// fn change_left_stick_values(mut query: Query<&mut InputMap>){ +/// let mut input_map = query.single_mut(); +/// +/// // Get the input at the 0 index since the left stick was added first in `Action::Look` +/// let input = input_map.get_mut(Action::Look).get_at_mut(0).unwrap(); +/// +/// // Some pattern matching is needed to get to the `DualAxis` +/// if let UserInput::Single(kind) = input{ +/// if let InputKind::DualAxis(dual_axis) = kind{ +/// // Here any value of the left stick `DualAxis` can be changed +/// dual_axis.x.sensitivity = 0.8; +/// dual_axis.y.sensitivity = 0.8; +/// dual_axis.deadzone = DeadZoneShape::Rect { width: 1.0, height: 1.0 } +/// } +/// } +/// } #[derive(Resource, Component, Debug, Clone, PartialEq, Eq, TypeUuid)] #[uuid = "D7DECC78-8573-42FF-851A-F0344C7D05C9"] pub struct InputMap { From e58d3d631a58de0686a9bf8c870ced6976e10879 Mon Sep 17 00:00:00 2001 From: Tomato <67799071+100-TomatoJuice@users.noreply.github.com> Date: Wed, 30 Aug 2023 19:10:14 -0700 Subject: [PATCH 10/13] Revert invert merge --- src/axislike.rs | 13 +++++++++++-- src/input_streams.rs | 2 ++ tests/gamepad_axis.rs | 13 +++++++++++++ tests/mouse_motion.rs | 9 +++++++++ tests/mouse_wheel.rs | 9 +++++++++ 5 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/axislike.rs b/src/axislike.rs index bb3f8608..3d4aebd3 100644 --- a/src/axislike.rs +++ b/src/axislike.rs @@ -28,10 +28,11 @@ pub struct SingleAxis { pub positive_low: f32, /// Any axis value lower than this will trigger the input. pub negative_low: f32, + /// Whether to invert output values from this axis. + pub inverted: bool, /// How sensitive the axis is to input values. /// /// Since sensitivity is a multiplier, any value `>1.0` will increase sensitivity while any value `<1.0` will decrease sensitivity. - /// Negative values will invert the axis. pub sensitivity: f32, /// The target value for this input, used for input mocking. /// @@ -47,6 +48,7 @@ impl SingleAxis { axis_type: axis_type.into(), positive_low: threshold, negative_low: -threshold, + inverted: false, sensitivity: 1.0, value: None, } @@ -62,6 +64,7 @@ impl SingleAxis { axis_type: axis_type.into(), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, value: Some(value), } @@ -74,6 +77,7 @@ impl SingleAxis { axis_type: AxisType::MouseWheel(MouseWheelAxisType::X), positive_low: 0., negative_low: 0., + inverted: false, sensitivity: 1.0, value: None, } @@ -86,6 +90,7 @@ impl SingleAxis { axis_type: AxisType::MouseWheel(MouseWheelAxisType::Y), positive_low: 0., negative_low: 0., + inverted: false, sensitivity: 1.0, value: None, } @@ -98,6 +103,7 @@ impl SingleAxis { axis_type: AxisType::MouseMotion(MouseMotionAxisType::X), positive_low: 0., negative_low: 0., + inverted: false, sensitivity: 1.0, value: None, } @@ -110,6 +116,7 @@ impl SingleAxis { axis_type: AxisType::MouseMotion(MouseMotionAxisType::Y), positive_low: 0., negative_low: 0., + inverted: false, sensitivity: 1.0, value: None, } @@ -123,6 +130,7 @@ impl SingleAxis { axis_type: axis_type.into(), negative_low: threshold, positive_low: f32::MAX, + inverted: false, sensitivity: 1.0, value: None, } @@ -136,6 +144,7 @@ impl SingleAxis { axis_type: axis_type.into(), negative_low: f32::MIN, positive_low: threshold, + inverted: false, sensitivity: 1.0, value: None, } @@ -159,7 +168,7 @@ impl SingleAxis { /// Returns this [`SingleAxis`] inverted. #[must_use] pub fn inverted(mut self) -> Self { - self.sensitivity = -self.sensitivity; + self.inverted = !self.inverted; self } } diff --git a/src/input_streams.rs b/src/input_streams.rs index 0632019c..f557dd72 100644 --- a/src/input_streams.rs +++ b/src/input_streams.rs @@ -265,6 +265,8 @@ impl<'a> InputStreams<'a> { let value_in_axis_range = |axis: &SingleAxis, value: f32| -> f32 { if value >= axis.negative_low && value <= axis.positive_low && include_deadzone { 0.0 + } else if axis.inverted { + -value * axis.sensitivity } else { value * axis.sensitivity } diff --git a/tests/gamepad_axis.rs b/tests/gamepad_axis.rs index cbf31052..cbababf4 100644 --- a/tests/gamepad_axis.rs +++ b/tests/gamepad_axis.rs @@ -80,6 +80,7 @@ fn game_pad_single_axis_mocking() { positive_low: 0.0, negative_low: 0.0, sensitivity: 1.0, + inverted: false, }; app.send_input(input); @@ -100,6 +101,7 @@ fn game_pad_dual_axis_mocking() { positive_low: 0.0, negative_low: 0.0, sensitivity: 1.0, + inverted: false, }, y: SingleAxis { axis_type: AxisType::Gamepad(GamepadAxisType::LeftStickY), @@ -107,6 +109,7 @@ fn game_pad_dual_axis_mocking() { positive_low: 0.0, negative_low: 0.0, sensitivity: 1.0, + inverted: false, }, deadzone: DualAxis::DEFAULT_DEADZONE_SHAPE, }; @@ -136,6 +139,7 @@ fn game_pad_single_axis() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -149,6 +153,7 @@ fn game_pad_single_axis() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -162,6 +167,7 @@ fn game_pad_single_axis() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -175,6 +181,7 @@ fn game_pad_single_axis() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -189,6 +196,7 @@ fn game_pad_single_axis() { // Usually a small deadzone threshold will be set positive_low: 0.1, negative_low: 0.1, + inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -202,6 +210,7 @@ fn game_pad_single_axis() { value: None, positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -230,6 +239,7 @@ fn game_pad_single_axis_inverted() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, + inverted: true, sensitivity: -1.0, } .inverted(); @@ -245,6 +255,7 @@ fn game_pad_single_axis_inverted() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, + inverted: true, sensitivity: -1.0, }; app.send_input(input); @@ -259,6 +270,7 @@ fn game_pad_single_axis_inverted() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, + inverted: true, sensitivity: -1.0, }; app.send_input(input); @@ -273,6 +285,7 @@ fn game_pad_single_axis_inverted() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, + inverted: true, sensitivity: -1.0, }; app.send_input(input); diff --git a/tests/mouse_motion.rs b/tests/mouse_motion.rs index 99564e98..fd8a575b 100644 --- a/tests/mouse_motion.rs +++ b/tests/mouse_motion.rs @@ -74,6 +74,7 @@ fn mouse_motion_single_axis_mocking() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }; @@ -94,6 +95,7 @@ fn mouse_motion_dual_axis_mocking() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }, y: SingleAxis { @@ -101,6 +103,7 @@ fn mouse_motion_dual_axis_mocking() { value: Some(0.), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }, deadzone: DualAxis::DEFAULT_DEADZONE_SHAPE, @@ -170,6 +173,7 @@ fn mouse_motion_single_axis() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -183,6 +187,7 @@ fn mouse_motion_single_axis() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -196,6 +201,7 @@ fn mouse_motion_single_axis() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -209,6 +215,7 @@ fn mouse_motion_single_axis() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -223,6 +230,7 @@ fn mouse_motion_single_axis() { // Usually a small deadzone threshold will be set positive_low: 0.1, negative_low: 0.1, + inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -236,6 +244,7 @@ fn mouse_motion_single_axis() { value: None, positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }; app.send_input(input); diff --git a/tests/mouse_wheel.rs b/tests/mouse_wheel.rs index 470e3d9b..72f46fcf 100644 --- a/tests/mouse_wheel.rs +++ b/tests/mouse_wheel.rs @@ -75,6 +75,7 @@ fn mouse_wheel_single_axis_mocking() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }; @@ -95,6 +96,7 @@ fn mouse_wheel_dual_axis_mocking() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }, y: SingleAxis { @@ -102,6 +104,7 @@ fn mouse_wheel_dual_axis_mocking() { value: Some(0.), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }, deadzone: DualAxis::DEFAULT_DEADZONE_SHAPE, @@ -171,6 +174,7 @@ fn mouse_wheel_single_axis() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -184,6 +188,7 @@ fn mouse_wheel_single_axis() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -197,6 +202,7 @@ fn mouse_wheel_single_axis() { value: Some(1.), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -210,6 +216,7 @@ fn mouse_wheel_single_axis() { value: Some(-1.), positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -224,6 +231,7 @@ fn mouse_wheel_single_axis() { // Usually a small deadzone threshold will be set positive_low: 0.1, negative_low: 0.1, + inverted: false, sensitivity: 1.0, }; app.send_input(input); @@ -237,6 +245,7 @@ fn mouse_wheel_single_axis() { value: None, positive_low: 0.0, negative_low: 0.0, + inverted: false, sensitivity: 1.0, }; app.send_input(input); From 735ddc639bda30f14847499fd9495fcdaf380ffe Mon Sep 17 00:00:00 2001 From: Tomato <67799071+100-TomatoJuice@users.noreply.github.com> Date: Wed, 30 Aug 2023 19:14:02 -0700 Subject: [PATCH 11/13] Fix doc --- src/input_map.rs | 187 ++++++++++++++++++++++++----------------------- 1 file changed, 95 insertions(+), 92 deletions(-) diff --git a/src/input_map.rs b/src/input_map.rs index 7cdfdf0b..8e9d3766 100644 --- a/src/input_map.rs +++ b/src/input_map.rs @@ -19,98 +19,101 @@ use std::collections::HashMap; use std::hash::Hash; use std::marker::PhantomData; -/// Maps from raw inputs to an input-method agnostic representation -/// -/// Multiple inputs can be mapped to the same action, -/// and each input can be mapped to multiple actions. -/// -/// The provided input types must be able to be converted into a [`UserInput`]. -/// -/// The maximum number of bindings (total) that can be stored for each action is 16. -/// Insertions will silently fail if you have reached this cap. -/// -/// By default, if two actions would be triggered by a combination of buttons, -/// and one combination is a strict subset of the other, only the larger input is registered. -/// For example, pressing both `S` and `Ctrl + S` in your text editor app would save your file, -/// but not enter the letters `s`. -/// Set the [`ClashStrategy`](crate::clashing_inputs::ClashStrategy) resource -/// to configure this behavior. -/// -/// # Example -/// ```rust -/// use bevy::prelude::*; -/// use leafwing_input_manager::prelude::*; -/// use leafwing_input_manager::user_input::InputKind; -/// -/// // You can Run! -/// // But you can't Hide :( -/// #[derive(Actionlike, Clone, Copy, PartialEq, Eq, Hash, Reflect)] -/// enum Action { -/// Run, -/// Hide, -/// } -/// -/// // Construction -/// let mut input_map = InputMap::new([ -/// // Note that the type of your iterators must be homogenous; -/// // you can use `InputKind` or `UserInput` if needed -/// // as unifying types -/// (GamepadButtonType::South, Action::Run), -/// (GamepadButtonType::LeftTrigger, Action::Hide), -/// (GamepadButtonType::RightTrigger, Action::Hide), -/// ]); -/// -/// // Insertion -/// input_map.insert(MouseButton::Left, Action::Run) -/// .insert(KeyCode::ShiftLeft, Action::Run) -/// // Chords -/// .insert_modified(Modifier::Control, KeyCode::R, Action::Run) -/// .insert_chord([InputKind::Keyboard(KeyCode::H), -/// InputKind::GamepadButton(GamepadButtonType::South), -/// InputKind::Mouse(MouseButton::Middle)], -/// Action::Run); -/// -/// // Removal -/// input_map.clear_action(Action::Hide); -///``` -/// -/// # Example -/// ```rust -/// use bevy::prelude::*; -/// use leafwing_input_manager::prelude::*; -/// use leafwing_input_manager::user_input::InputKind; -/// -/// #[derive(Actionlike, PartialEq, Eq, Clone, Copy, Hash, Debug, Reflect)] -/// enum Action { -/// Look, -/// } -/// -/// fn spawn_player(mut commands: Commands){ -/// commands.spawn(InputManagerBundle:: { -/// action_state: ActionState::default(), -/// input_map: InputMap::default() -/// .insert(DualAxis::left_stick().with_sensitivity(1.0, 1.0), Action::Look) -/// .insert(DualAxis::mouse_motion().with_sensitivity(1.0, 1.0), Action::Look) -/// .build(), -/// }); -/// } -/// -/// fn change_left_stick_values(mut query: Query<&mut InputMap>){ -/// let mut input_map = query.single_mut(); -/// -/// // Get the input at the 0 index since the left stick was added first in `Action::Look` -/// let input = input_map.get_mut(Action::Look).get_at_mut(0).unwrap(); -/// -/// // Some pattern matching is needed to get to the `DualAxis` -/// if let UserInput::Single(kind) = input{ -/// if let InputKind::DualAxis(dual_axis) = kind{ -/// // Here any value of the left stick `DualAxis` can be changed -/// dual_axis.x.sensitivity = 0.8; -/// dual_axis.y.sensitivity = 0.8; -/// dual_axis.deadzone = DeadZoneShape::Rect { width: 1.0, height: 1.0 } -/// } -/// } -/// } +/** +Maps from raw inputs to an input-method agnostic representation + +Multiple inputs can be mapped to the same action, +and each input can be mapped to multiple actions. + +The provided input types must be able to be converted into a [`UserInput`]. + +The maximum number of bindings (total) that can be stored for each action is 16. +Insertions will silently fail if you have reached this cap. + +By default, if two actions would be triggered by a combination of buttons, +and one combination is a strict subset of the other, only the larger input is registered. +For example, pressing both `S` and `Ctrl + S` in your text editor app would save your file, +but not enter the letters `s`. +Set the [`ClashStrategy`](crate::clashing_inputs::ClashStrategy) resource +to configure this behavior. + +# Example +```rust +use bevy::prelude::*; +use leafwing_input_manager::prelude::*; +use leafwing_input_manager::user_input::InputKind; + +// You can Run! +// But you can't Hide :( +#[derive(Actionlike, Clone, Copy, PartialEq, Eq, Hash, Reflect)] +enum Action { + Run, + Hide, +} + +// Construction +let mut input_map = InputMap::new([ + // Note that the type of your iterators must be homogenous; + // you can use `InputKind` or `UserInput` if needed + // as unifying types + (GamepadButtonType::South, Action::Run), + (GamepadButtonType::LeftTrigger, Action::Hide), + (GamepadButtonType::RightTrigger, Action::Hide), +]); + +// Insertion +input_map.insert(MouseButton::Left, Action::Run) +.insert(KeyCode::ShiftLeft, Action::Run) +// Chords +.insert_modified(Modifier::Control, KeyCode::R, Action::Run) +.insert_chord([InputKind::Keyboard(KeyCode::H), + InputKind::GamepadButton(GamepadButtonType::South), + InputKind::Mouse(MouseButton::Middle)], + Action::Run); + +// Removal +input_map.clear_action(Action::Hide); +``` + +# Example +```rust +use bevy::prelude::*; +use leafwing_input_manager::prelude::*; +use leafwing_input_manager::user_input::InputKind; + +#[derive(Actionlike, PartialEq, Eq, Clone, Copy, Hash, Debug, Reflect)] +enum Action { + Look, +} + +fn spawn_player(mut commands: Commands){ + commands.spawn(InputManagerBundle:: { + action_state: ActionState::default(), + input_map: InputMap::default() + .insert(DualAxis::left_stick().with_sensitivity(1.0, 1.0), Action::Look) + .insert(DualAxis::mouse_motion().with_sensitivity(1.0, 1.0), Action::Look) + .build(), + }); +} + +fn change_left_stick_values(mut query: Query<&mut InputMap>){ + let mut input_map = query.single_mut(); + + // Get the input at the 0 index since the left stick was added first in `Action::Look` + let input = input_map.get_mut(Action::Look).get_at_mut(0).unwrap(); + + // Some pattern matching is needed to get to the `DualAxis` + if let UserInput::Single(kind) = input{ + if let InputKind::DualAxis(dual_axis) = kind{ + // Here any value of the left stick `DualAxis` can be changed + dual_axis.x.sensitivity = 0.8; + dual_axis.y.sensitivity = 0.8; + dual_axis.deadzone = DeadZoneShape::Rect { width: 1.0, height: 1.0 } + } + } +} +``` +**/ #[derive(Resource, Component, Debug, Clone, PartialEq, Eq, TypeUuid)] #[uuid = "D7DECC78-8573-42FF-851A-F0344C7D05C9"] pub struct InputMap { From d014c66535262c391384e65f5ba7732c20513913 Mon Sep 17 00:00:00 2001 From: Tomato <67799071+100-TomatoJuice@users.noreply.github.com> Date: Wed, 30 Aug 2023 19:15:25 -0700 Subject: [PATCH 12/13] cargo fmt --- src/input_map.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/input_map.rs b/src/input_map.rs index 8e9d3766..9d59be33 100644 --- a/src/input_map.rs +++ b/src/input_map.rs @@ -98,7 +98,7 @@ fn spawn_player(mut commands: Commands){ fn change_left_stick_values(mut query: Query<&mut InputMap>){ let mut input_map = query.single_mut(); - + // Get the input at the 0 index since the left stick was added first in `Action::Look` let input = input_map.get_mut(Action::Look).get_at_mut(0).unwrap(); From 8df5ab1e0b6e21c583f2f0bfb7558e391af99149 Mon Sep 17 00:00:00 2001 From: Tomato <67799071+100-TomatoJuice@users.noreply.github.com> Date: Thu, 31 Aug 2023 08:14:03 -0700 Subject: [PATCH 13/13] Apply suggestions from code review Co-authored-by: Alice Cecile --- RELEASES.md | 2 +- src/axislike.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 8ec3b9fb..1081aba2 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -12,7 +12,7 @@ ### Enhancements - Added `DeadZoneShape` for `DualAxis` which allows for different deadzones shapes: cross, rectangle, and ellipse. -- Added sensitivity for `SingleAxis` and `DualAxis`. +- Added sensitivity for `SingleAxis` and `DualAxis`, allowing you to scale mouse, keypad and gamepad inputs differently for each action. ## Version 0.10 diff --git a/src/axislike.rs b/src/axislike.rs index 3d4aebd3..f9ee87e3 100644 --- a/src/axislike.rs +++ b/src/axislike.rs @@ -33,6 +33,8 @@ pub struct SingleAxis { /// How sensitive the axis is to input values. /// /// Since sensitivity is a multiplier, any value `>1.0` will increase sensitivity while any value `<1.0` will decrease sensitivity. + /// This value should always be strictly positive: a value of 0 will cause the axis to stop functioning, + /// while negative values will invert the direction. pub sensitivity: f32, /// The target value for this input, used for input mocking. ///