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.
///