leafwing_input_manager/
lib.rs

1#![forbid(missing_docs)]
2#![warn(clippy::doc_markdown)]
3#![doc = include_str!("../README.md")]
4
5use crate::action_state::ActionState;
6use crate::input_map::InputMap;
7use bevy::ecs::prelude::*;
8use bevy::reflect::{FromReflect, Reflect, TypePath, Typed};
9use serde::{Deserialize, Serialize};
10use std::fmt::Debug;
11use std::hash::Hash;
12
13pub mod action_diff;
14pub mod action_state;
15pub mod axislike;
16pub mod buttonlike;
17pub mod clashing_inputs;
18pub mod common_conditions;
19pub mod input_map;
20pub mod input_processing;
21pub mod plugin;
22pub mod systems;
23
24#[cfg(feature = "timing")]
25pub mod timing;
26pub mod typetag;
27pub mod user_input;
28
29// Importing the derive macro
30pub use leafwing_input_manager_macros::Actionlike;
31
32/// Everything you need to get started
33pub mod prelude {
34    pub use crate::InputControlKind;
35
36    pub use crate::action_state::ActionState;
37    pub use crate::clashing_inputs::ClashStrategy;
38    pub use crate::input_map::InputMap;
39    pub use crate::input_processing::*;
40    pub use crate::user_input::*;
41
42    pub use crate::plugin::InputManagerPlugin;
43    pub use crate::Actionlike;
44    #[expect(
45        deprecated,
46        reason = "This needs to be supported for until InputManagerBundle is removed"
47    )]
48    pub use crate::InputManagerBundle;
49
50    pub use leafwing_input_manager_macros::serde_typetag;
51}
52
53/// Allows a type to be used as a gameplay action in an input-agnostic fashion
54///
55/// Actions are modelled as "virtual buttons" (or axes), cleanly abstracting over messy, customizable inputs
56/// in a way that can be easily consumed by your game logic.
57///
58/// This trait should be implemented on the `A` type that you want to pass into [`InputManagerPlugin`](crate::plugin::InputManagerPlugin).
59///
60/// Generally, these types will be very small (often data-less) enums.
61/// As a result, the APIs in this crate accept actions by value, rather than reference.
62/// While `Copy` is not a required trait bound,
63/// users are strongly encouraged to derive `Copy` on these enums whenever possible to improve ergonomics.
64///
65/// # Examples
66///
67/// ```rust
68/// use bevy::prelude::Reflect;
69/// use leafwing_input_manager::Actionlike;
70///
71/// #[derive(Actionlike, Debug, PartialEq, Eq, Clone, Copy, Hash, Reflect)]
72/// enum PlayerAction {
73///    // Movement
74///    Up,
75///    Down,
76///    Left,
77///    Right,
78///    // Abilities
79///    Ability1,
80///    Ability2,
81///    Ability3,
82///    Ability4,
83///    Ultimate,
84/// }
85/// ```
86///
87/// # Customizing variant behavior
88///
89/// By default, the derive macro for this trait assumes that all actions are buttonlike.
90///
91/// You can customize this behavior by using the `#[actionlike]` attribute,
92/// either on the entire enum or on individual variants.
93///
94/// See the document of [`InputControlKind`] for available options.
95///
96/// ```rust
97/// use bevy::prelude::*;
98/// use leafwing_input_manager::prelude::*;
99///
100/// #[derive(Actionlike, Debug, PartialEq, Eq, Clone, Copy, Hash, Reflect)]
101/// #[actionlike(Axis)] // This attribute applies to all variants in the enum
102/// enum CameraAction {
103///    Zoom,  // This action is controlled by axes
104///    #[actionlike(DualAxis)]
105///    Move,  // This action is controlled by dual axes since we have overridden the default option
106///    #[actionlike(Button)]
107///    TakePhoto, // This action is controlled by buttons since we have overridden the default option
108/// }
109/// ```
110pub trait Actionlike:
111    Debug + Eq + Hash + Send + Sync + Clone + Reflect + Typed + TypePath + FromReflect + 'static
112{
113    /// Returns the kind of input control this action represents: buttonlike, axislike, or dual-axislike.
114    fn input_control_kind(&self) -> InputControlKind;
115}
116
117/// This [`Bundle`] allows entities to collect and interpret inputs from across input sources
118///
119/// Use with [`InputManagerPlugin`](crate::plugin::InputManagerPlugin), providing the same enum type to both.
120#[derive(Bundle)]
121#[deprecated(
122    since = "0.17.0",
123    note = "Insert `InputMap` directly (and optionally `ActionState`) instead."
124)]
125pub struct InputManagerBundle<A: Actionlike> {
126    /// An [`ActionState`] component
127    pub action_state: ActionState<A>,
128    /// An [`InputMap`] component
129    pub input_map: InputMap<A>,
130}
131
132// Cannot use derive(Default), as it forces an undesirable bound on our generics
133#[expect(
134    deprecated,
135    reason = "This needs to be supported for until InputManagerBundle is removed"
136)]
137impl<A: Actionlike> Default for InputManagerBundle<A> {
138    fn default() -> Self {
139        Self {
140            action_state: ActionState::default(),
141            input_map: InputMap::default(),
142        }
143    }
144}
145
146#[expect(
147    deprecated,
148    reason = "This needs to be supported for until InputManagerBundle is removed"
149)]
150impl<A: Actionlike> InputManagerBundle<A> {
151    /// Creates a [`InputManagerBundle`] with the given [`InputMap`].
152    pub fn with_map(input_map: InputMap<A>) -> Self {
153        Self {
154            input_map,
155            action_state: ActionState::default(),
156        }
157    }
158}
159
160/// Classifies [`UserInput`](crate::user_input::UserInput)s and [`Actionlike`] actions based on their behavior (buttons, analog axes, etc.).
161#[derive(Debug, Clone, Copy, PartialEq, Reflect, Serialize, Deserialize)]
162#[must_use]
163pub enum InputControlKind {
164    /// A single input with binary state (active or inactive), typically a button press (on or off).
165    ///
166    /// Corresponds to [`Buttonlike`](crate::user_input::Buttonlike)  inputs.
167    Button,
168
169    /// A single analog or digital input, often used for range controls like a thumb stick on a gamepad or mouse wheel,
170    /// providing a value within a min-max range.
171    ///
172    /// Corresponds to [`Axislike`](crate::user_input::Axislike) inputs.
173    Axis,
174
175    /// A combination of two axis-like inputs, often used for directional controls like a D-pad on a gamepad,
176    /// providing separate values for the X and Y axes.
177    ///
178    /// Corresponds to [`DualAxislike`](crate::user_input::DualAxislike) inputs.
179    DualAxis,
180
181    /// A combination of three axis-like inputs, providing separate values for the X, Y and Z axes.
182    ///
183    /// Corresponds to [`TripleAxislike`](crate::user_input::TripleAxislike) inputs.
184    TripleAxis,
185}