Skip to main content

bevy_enhanced_input/
condition.rs

1/*!
2Instead of hardcoded states like "pressed" or "released", all actions use an abstract [`TriggerState`] component
3(which is a required component of [`Action<C>`]). Its meaning depends on the assigned [input conditions](crate::condition),
4which determine when the action is triggered. This allows you to define flexible behaviors, such as "hold for 1 second".
5
6Input conditions are components that implement [`InputCondition`] trait. Similar to modifiers, you can attach them to
7both actions and bindings. They also evaluated during [`EnhancedInputSystems::Update`] right after modifiers in their insertion
8order and update [`TriggerState`] on the associated action entity.
9
10If no conditions are attached, the action behaves like with [`Down`] condition with a zero actuation threshold,
11meaning it will trigger on any non-zero input value.
12
13# Examples
14
15```
16use bevy::prelude::*;
17use bevy_enhanced_input::prelude::*;
18
19#[derive(Component)]
20struct Player;
21
22#[derive(InputAction)]
23#[action_output(bool)]
24struct Jump;
25
26#[derive(InputAction)]
27#[action_output(bool)]
28struct Fire;
29
30let mut world = World::new();
31world.spawn((
32    Player,
33    actions!(Player[
34        (
35            // The action will trigger only if held for 1 second.
36            Action::<Jump>::new(),
37            Hold::new(1.0),
38            bindings![KeyCode::Space, GamepadButton::South],
39        ),
40        (
41            Action::<Fire>::new(),
42            Pulse::new(0.5), // The action will trigger every 0.5 seconds while held.
43            bindings![
44                (GamepadButton::RightTrigger2, Down::new(0.3)), // Additionally the right trigger only counts if its value is greater than 0.3.
45                MouseButton::Left,
46            ]
47        ),
48    ])
49));
50```
51*/
52
53pub mod block_by;
54pub mod chord;
55pub mod combo;
56pub mod cooldown;
57pub mod down;
58pub mod fns;
59pub mod hold;
60pub mod hold_and_release;
61pub mod press;
62pub mod pulse;
63pub mod release;
64pub mod tap;
65pub mod toggle;
66
67use core::fmt::Debug;
68
69use crate::prelude::*;
70
71/// Default actuation threshold for all conditions.
72pub const DEFAULT_ACTUATION: f32 = 0.5;
73
74/// Defines how input activates.
75///
76/// Conditions analyze the input, checking for minimum actuation values
77/// and validating patterns like short taps, prolonged holds, or the typical "press"
78/// or "release" events.
79///
80/// Can be attached both to bindings and actions.
81///
82/// If you create a custom condition, it needs to be registered using
83/// [`InputConditionAppExt::add_input_condition`].
84pub trait InputCondition: Debug {
85    /// Returns calculates state.
86    ///
87    /// `actions` is a state of other actions within the currently evaluating context.
88    fn evaluate(
89        &mut self,
90        actions: &ActionsQuery,
91        time: &ContextTime,
92        value: ActionValue,
93    ) -> TriggerState;
94
95    /// Returns how the condition is combined with others.
96    fn kind(&self) -> ConditionKind {
97        ConditionKind::Explicit
98    }
99}
100
101/// Determines how a condition contributes to the final [`TriggerState`].
102///
103/// If no conditions are provided, the state will be set to [`TriggerState::Fired`]
104/// on any non-zero value, functioning similarly to a [`Down`] condition
105/// with a zero actuation threshold.
106///
107/// For details about how actions are combined, see [`Actions`].
108pub enum ConditionKind {
109    /// The most significant [`TriggerState`] from all explicit conditions will be the
110    /// resulting state.
111    Explicit,
112    /// Like [`Self::Explicit`], but [`TriggerState::Fired`] will be set only if all
113    /// implicit conditions return it.
114    ///
115    /// Otherwise, the most significant state will be capped at [`TriggerState::Ongoing`].
116    Implicit,
117    /// Any blocking condition that returns [`TriggerState::None`] will override
118    /// the state with [`TriggerState::None`].
119    ///
120    /// Doesn't contribute to the state on its own.
121    Blocker,
122}