diff --git a/Source/Engine/Input/Enums.h b/Source/Engine/Input/Enums.h index 80e10786f..82498f500 100644 --- a/Source/Engine/Input/Enums.h +++ b/Source/Engine/Input/Enums.h @@ -263,6 +263,37 @@ API_ENUM() enum class InputActionMode Release = 2, }; +/// +/// The input action event phases. +/// +API_ENUM() enum class InputActionState +{ + /// + /// The key/button is not assigned. + /// + None = 0, + + /// + /// The key/button is waiting for input. + /// + Waiting = 1, + + /// + /// User is pressing the key/button. + /// + Pressing = 2, + + /// + /// User pressed the key/button (but wasn't pressing it in the previous frame). + /// + Press = 3, + + /// + /// User released the key/button (was pressing it in the previous frame). + /// + Release = 4, +}; + /// /// The input gamepad index. /// diff --git a/Source/Engine/Input/Input.cpp b/Source/Engine/Input/Input.cpp index 7a4547c62..8658b984c 100644 --- a/Source/Engine/Input/Input.cpp +++ b/Source/Engine/Input/Input.cpp @@ -25,15 +25,17 @@ struct AxisEvaluation bool Used; }; -struct ActionData +struct ActionData { bool Active; uint64 FrameIndex; + InputActionState State; ActionData() { Active = false; FrameIndex = 0; + State = InputActionState::Waiting; } }; @@ -597,6 +599,16 @@ bool Input::GetAction(const StringView& name) return e ? e->Active : false; } +InputActionState Input::GetActionState(const StringView& name) +{ + const auto e = Actions.TryGet(name); + if (e != nullptr) + { + return e->State; + } + return InputActionState::None; +} + float Input::GetAxis(const StringView& name) { const auto e = Axes.TryGet(name); @@ -806,6 +818,7 @@ void InputService::Update() ActionData& data = Actions[name]; data.Active = false; + data.State = InputActionState::Waiting; // Mark as updated in this frame data.FrameIndex = frame; @@ -830,6 +843,19 @@ void InputService::Update() isActive = Input::GetKeyUp(config.Key) || Input::GetMouseButtonUp(config.MouseButton) || Input::GetGamepadButtonUp(config.Gamepad, config.GamepadButton); } + if (Input::GetKeyDown(config.Key) || Input::GetMouseButtonDown(config.MouseButton) || Input::GetGamepadButtonDown(config.Gamepad, config.GamepadButton)) + { + data.State = InputActionState::Press; + } + else if (Input::GetKey(config.Key) || Input::GetMouseButton(config.MouseButton) || Input::GetGamepadButton(config.Gamepad, config.GamepadButton)) + { + data.State = InputActionState::Pressing; + } + else if (Input::GetKeyUp(config.Key) || Input::GetMouseButtonUp(config.MouseButton) || Input::GetGamepadButtonUp(config.Gamepad, config.GamepadButton)) + { + data.State = InputActionState::Release; + } + data.Active |= isActive; } diff --git a/Source/Engine/Input/Input.h b/Source/Engine/Input/Input.h index d9f86076b..1fcb352ea 100644 --- a/Source/Engine/Input/Input.h +++ b/Source/Engine/Input/Input.h @@ -309,6 +309,14 @@ public: /// API_FUNCTION() static bool GetAction(const StringView& name); + /// + /// Gets the value of the virtual action identified by name. Use to get the current config. + /// + /// The action name. + /// A InputActionPhase determining the current phase of the Action (e.g If it was just pressed, is being held or just released). + /// + API_FUNCTION() static InputActionState GetActionState(const StringView& name); + /// /// Gets the value of the virtual axis identified by name. Use to get the current config. ///