From 44f83c1f186334b147745a5cd21323386003f6ce Mon Sep 17 00:00:00 2001 From: Steve Streeting Date: Tue, 1 Feb 2022 16:58:20 +0000 Subject: [PATCH] Add the option to detect last axis move separately to input mode --- .../Private/StevesGameSubsystem.cpp | 38 +++++++++++++++++++ .../Public/StevesGameSubsystem.h | 13 +++++++ 2 files changed, 51 insertions(+) diff --git a/Source/StevesUEHelpers/Private/StevesGameSubsystem.cpp b/Source/StevesUEHelpers/Private/StevesGameSubsystem.cpp index c864010..9a0b0a7 100644 --- a/Source/StevesUEHelpers/Private/StevesGameSubsystem.cpp +++ b/Source/StevesUEHelpers/Private/StevesGameSubsystem.cpp @@ -36,6 +36,7 @@ void UStevesGameSubsystem::CreateInputDetector() InputDetector->OnInputModeChanged.BindUObject(this, &UStevesGameSubsystem::OnInputDetectorModeChanged); InputDetector->OnButtonInputModeChanged.BindUObject(this, &UStevesGameSubsystem::OnButtonInputDetectorModeChanged); + InputDetector->OnAxisInputModeChanged.BindUObject(this, &UStevesGameSubsystem::OnAxisInputDetectorModeChanged); } } @@ -130,6 +131,13 @@ void UStevesGameSubsystem::OnButtonInputDetectorModeChanged(int PlayerIndex, EIn OnButtonInputModeChanged.Broadcast(PlayerIndex, NewMode); } +void UStevesGameSubsystem::OnAxisInputDetectorModeChanged(int PlayerIndex, EInputMode NewMode) +{ + // This is specifically for button changes; if this is a different main input mode it will also be registered in OnInputDetectorModeChanged + // Just relay this one + OnAxisInputModeChanged.Broadcast(PlayerIndex, NewMode); +} + FFocusSystem* UStevesGameSubsystem::GetFocusSystem() { return &FocusSystem; @@ -295,6 +303,7 @@ UStevesGameSubsystem::FInputModeDetector::FInputModeDetector() // 4 local players should be plenty usually (will expand if necessary) LastInputModeByPlayer.Init(DefaultInputMode, 4); LastButtonPressByPlayer.Init(DefaultButtonInputMode, 4); + LastAxisMoveByPlayer.Init(DefaultAxisInputMode, 4); } bool UStevesGameSubsystem::FInputModeDetector::HandleKeyDownEvent(FSlateApplication& SlateApp, const FKeyEvent& InKeyEvent) @@ -378,6 +387,15 @@ EInputMode UStevesGameSubsystem::FInputModeDetector::GetLastButtonInputMode(int return DefaultButtonInputMode; } +EInputMode UStevesGameSubsystem::FInputModeDetector::GetLastAxisInputMode(int PlayerIndex) +{ + if (PlayerIndex >= 0 && PlayerIndex < LastAxisMoveByPlayer.Num()) + return LastAxisMoveByPlayer[PlayerIndex]; + + // Assume default if never told + return DefaultAxisInputMode; +} + void UStevesGameSubsystem::FInputModeDetector::ProcessKeyOrButton(int PlayerIndex, FKey Key) { if (Key.IsGamepadKey()) @@ -420,6 +438,7 @@ bool UStevesGameSubsystem::FInputModeDetector::IsAGamepadButton(const FKey& Key) void UStevesGameSubsystem::FInputModeDetector::SetMode(int PlayerIndex, EInputMode NewMode, bool bIsButton) { bool bButtonChanged = false; + bool bAxisChanged = false; bool bMainChanged = false; if (bIsButton) @@ -434,6 +453,19 @@ void UStevesGameSubsystem::FInputModeDetector::SetMode(int PlayerIndex, EInputMo bButtonChanged = true; } } + else + { + if (NewMode != EInputMode::Unknown && NewMode != GetLastAxisInputMode(PlayerIndex)) + { + if (PlayerIndex >= LastAxisMoveByPlayer.Num()) + LastAxisMoveByPlayer.SetNum(PlayerIndex + 1); + + LastAxisMoveByPlayer[PlayerIndex] = NewMode; + + bAxisChanged = true; + } + + } // Whether it's a button or not it can affect the main input mode if (NewMode != EInputMode::Unknown && NewMode != GetLastInputMode(PlayerIndex)) { @@ -452,6 +484,12 @@ void UStevesGameSubsystem::FInputModeDetector::SetMode(int PlayerIndex, EInputMo OnButtonInputModeChanged.ExecuteIfBound(PlayerIndex, NewMode); //UE_LOG(LogStevesUEHelpers, Display, TEXT("Button mode for player %d changed: %s"), PlayerIndex, *UEnum::GetValueAsString(NewMode)); } + if (bAxisChanged) + { + // ReSharper disable once CppExpressionWithoutSideEffects + OnAxisInputModeChanged.ExecuteIfBound(PlayerIndex, NewMode); + //UE_LOG(LogStevesUEHelpers, Display, TEXT("Axis mode for player %d changed: %s"), PlayerIndex, *UEnum::GetValueAsString(NewMode)); + } if (bMainChanged) { // ReSharper disable once CppExpressionWithoutSideEffects diff --git a/Source/StevesUEHelpers/Public/StevesGameSubsystem.h b/Source/StevesUEHelpers/Public/StevesGameSubsystem.h index f0b66cc..9a583d2 100644 --- a/Source/StevesUEHelpers/Public/StevesGameSubsystem.h +++ b/Source/StevesUEHelpers/Public/StevesGameSubsystem.h @@ -65,9 +65,11 @@ protected: protected: TArray LastInputModeByPlayer; TArray LastButtonPressByPlayer; + TArray LastAxisMoveByPlayer; const EInputMode DefaultInputMode = EInputMode::Mouse; const EInputMode DefaultButtonInputMode = EInputMode::Keyboard; + const EInputMode DefaultAxisInputMode = EInputMode::Mouse; const float MouseMoveThreshold = 1; const float GamepadAxisThreshold = 0.2; @@ -80,6 +82,8 @@ protected: FInternalInputModeChanged OnInputModeChanged; /// Event raised when button input mode changes only FInternalInputModeChanged OnButtonInputModeChanged; + /// Event raised when axis input mode changes only + FInternalInputModeChanged OnAxisInputModeChanged; FInputModeDetector(); @@ -96,6 +100,8 @@ protected: EInputMode GetLastInputMode(int PlayerIndex = 0); /// Get the last input mode from button inputs (ignores axis changes, good for detecting if keyboard or mouse buttons are being used) EInputMode GetLastButtonInputMode(int PlayerIndex = 0); + /// Get the last input mode from axis movement (ignores button presses, good for detecting if keyboard or mouse axes are being used for motion) + EInputMode GetLastAxisInputMode(int PlayerIndex = 0); // Needed but unused virtual void Tick(const float DeltaTime, FSlateApplication& SlateApp, TSharedRef Cursor) override {} @@ -131,6 +137,7 @@ protected: // Called by detector void OnInputDetectorModeChanged(int PlayerIndex, EInputMode NewMode); void OnButtonInputDetectorModeChanged(int PlayerIndex, EInputMode NewMode); + void OnAxisInputDetectorModeChanged(int PlayerIndex, EInputMode NewMode); TSoftObjectPtr GetGamepadImages(int PlayerIndex, const UUiTheme* Theme); @@ -148,6 +155,12 @@ public: UPROPERTY(BlueprintAssignable) FOnInputModeChanged OnButtonInputModeChanged; + /// Event raised when the last axis input changed between gamepad / keyboard / mouse + /// This can happen at a different time to OnInputModeChanged, e.g. if that was triggered by a button press, but the + /// last axis moved was still mouse, you'd get this event later + UPROPERTY(BlueprintAssignable) + FOnInputModeChanged OnAxisInputModeChanged; + /// Event raised when the game window's foreground status changes UPROPERTY(BlueprintAssignable) FOnWindowForegroundChanged OnWindowForegroundChanged;