bevy_enhanced_input/input_modifier/
scale.rs

1use bevy::prelude::*;
2
3use super::InputModifier;
4use crate::{action_map::ActionMap, action_value::ActionValue};
5
6/// Scales input independently along each axis by a specified factor.
7///
8/// [`ActionValue::Bool`] will be converted into [`ActionValue::Axis1D`].
9#[derive(Clone, Copy, Debug)]
10pub struct Scale {
11    /// The factor applied to the input value.
12    ///
13    /// For example, if the factor is set to `Vec3::new(2.0, 2.0, 2.0)`, each input axis will be multiplied by 2.0.
14    pub factor: Vec3,
15}
16
17impl Scale {
18    /// Creates a new instance with all axes set to `value`.
19    #[must_use]
20    pub fn splat(value: f32) -> Self {
21        Self::new(Vec3::splat(value))
22    }
23
24    #[must_use]
25    pub fn new(factor: Vec3) -> Self {
26        Self { factor }
27    }
28}
29
30impl InputModifier for Scale {
31    fn apply(
32        &mut self,
33        _action_map: &ActionMap,
34        _time: &Time<Virtual>,
35        value: ActionValue,
36    ) -> ActionValue {
37        match value {
38            ActionValue::Bool(value) => {
39                let value = if value { 1.0 } else { 0.0 };
40                (value * self.factor.x).into()
41            }
42            ActionValue::Axis1D(value) => (value * self.factor.x).into(),
43            ActionValue::Axis2D(value) => (value * self.factor.xy()).into(),
44            ActionValue::Axis3D(value) => (value * self.factor).into(),
45        }
46    }
47}
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52
53    #[test]
54    fn scaling() {
55        let mut modifier = Scale::splat(2.0);
56        let action_map = ActionMap::default();
57        let time = Time::default();
58
59        assert_eq!(modifier.apply(&action_map, &time, true.into()), 2.0.into());
60        assert_eq!(modifier.apply(&action_map, &time, false.into()), 0.0.into());
61        assert_eq!(modifier.apply(&action_map, &time, 1.0.into()), 2.0.into());
62        assert_eq!(
63            modifier.apply(&action_map, &time, Vec2::ONE.into()),
64            (2.0, 2.0).into()
65        );
66        assert_eq!(
67            modifier.apply(&action_map, &time, Vec3::ONE.into()),
68            (2.0, 2.0, 2.0).into()
69        );
70    }
71}