diff --git a/Source/StevesUEHelpers/Private/StevesGameSubsystem.cpp b/Source/StevesUEHelpers/Private/StevesGameSubsystem.cpp index 6f920e7..b16344e 100644 --- a/Source/StevesUEHelpers/Private/StevesGameSubsystem.cpp +++ b/Source/StevesUEHelpers/Private/StevesGameSubsystem.cpp @@ -1,6 +1,7 @@ #include "StevesGameSubsystem.h" #include "EngineUtils.h" +#include "EnhancedInputComponent.h" #include "EnhancedInputSubsystems.h" #include "StevesGameViewportClientBase.h" #include "StevesPluginSettings.h" @@ -107,6 +108,34 @@ TSoftObjectPtr UStevesGameSubsystem::FindEnhancedInputAction(const return nullptr; } +void UStevesGameSubsystem::RegisterInterestInEnhancedInputAction(const UInputAction* Action, ETriggerEvent TriggerEvent) +{ + // Avoid registering duplicate interest + FEnhancedInputInterest Interest(Action, TriggerEvent); + if (!RegisteredEnhancedInputActionInterests.Contains(Interest)) + { + if (auto GI = GetGameInstance()) + { + if (auto PC = GI->GetFirstLocalPlayerController()) + { + if (auto EIC = Cast(PC->InputComponent)) + { + EIC->BindAction(Action, TriggerEvent, this, &ThisClass::EnhancedInputActionTriggered); + RegisteredEnhancedInputActionInterests.Add(Interest); + } + } + } + } + +} + +void UStevesGameSubsystem::EnhancedInputActionTriggered(const FInputActionInstance& InputActionInstance) +{ + OnEnhancedInputActionTriggered.Broadcast(InputActionInstance.GetSourceAction(), InputActionInstance.GetTriggerEvent()); +} + + + void UStevesGameSubsystem::InitTheme() { DefaultUiTheme = LoadObject(nullptr, *DefaultUiThemePath, nullptr); diff --git a/Source/StevesUEHelpers/Public/StevesGameSubsystem.h b/Source/StevesUEHelpers/Public/StevesGameSubsystem.h index 16080ab..717d498 100644 --- a/Source/StevesUEHelpers/Public/StevesGameSubsystem.h +++ b/Source/StevesUEHelpers/Public/StevesGameSubsystem.h @@ -10,12 +10,14 @@ #include "StevesUI/FocusSystem.h" #include "StevesUI/InputImage.h" #include "StevesUI/UiTheme.h" +#include "Templates/TypeHash.h" #include "StevesGameSubsystem.generated.h" DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnInputModeChanged, int, PlayerIndex, EInputMode, InputMode); DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnEnhancedInputMappingsChanged); DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnWindowForegroundChanged, bool, bFocussed); +DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnEnhancedInputActionTriggered, const UInputAction*, Action, ETriggerEvent, TriggeredEvent); /// Entry point for all the top-level features of the helper system UCLASS(Config=Game) @@ -33,7 +35,33 @@ protected: /// so that it's included when packaging UPROPERTY(Config) FString DefaultUiThemePath; - + + struct FEnhancedInputInterest + { + + TWeakObjectPtr Action; + ETriggerEvent Trigger; + FEnhancedInputInterest(const UInputAction* TheAction, ETriggerEvent TheTriggerEvent) : Action(TheAction), Trigger(TheTriggerEvent) {} + + + friend uint32 GetTypeHash(const FEnhancedInputInterest& Arg) + { + return HashCombine(GetTypeHash(Arg.Action), GetTypeHash(Arg.Trigger)); + } + + friend bool operator==(const FEnhancedInputInterest& Lhs, const FEnhancedInputInterest& RHS) + { + return Lhs.Action == RHS.Action + && Lhs.Trigger == RHS.Trigger; + } + + friend bool operator!=(const FEnhancedInputInterest& Lhs, const FEnhancedInputInterest& RHS) + { + return !(Lhs == RHS); + } + }; + + TSet RegisteredEnhancedInputActionInterests; public: virtual void Initialize(FSubsystemCollectionBase& Collection) override; @@ -143,7 +171,9 @@ protected: TSoftObjectPtr GetGamepadImages(int PlayerIndex, const UUiTheme* Theme); UPaperSprite* GetImageSpriteFromTable(const FKey& Key, const TSoftObjectPtr& Asset); - + UFUNCTION() + void EnhancedInputActionTriggered(const FInputActionInstance& InputActionInstance); + public: /// Event raised when main input mode changed between gamepad and keyboard / mouse (for any of axis / button events) @@ -167,6 +197,11 @@ public: /// plugin provides NO events to monitor it (sigh) UPROPERTY(BlueprintAssignable) FOnEnhancedInputMappingsChanged OnEnhancedInputMappingsChanged; + + /// Event fired when an enhanced input event that an interest has previously been registered in triggers. + /// Nothing will fire on this event unless you call RegisterInterestInEnhancedInputAction to listen for it. + UPROPERTY(BlueprintAssignable) + FOnEnhancedInputActionTriggered OnEnhancedInputActionTriggered; /// Event raised when the game window's foreground status changes UPROPERTY(BlueprintAssignable) @@ -301,4 +336,10 @@ public: */ TSoftObjectPtr FindEnhancedInputAction(const FString& Name); + + /// Register an interest in an enhanced input action. Calling this will result in OnEnhancedInputActionTriggered being called + /// when this action is triggered. + /// This is mainly for use in UI bindings. You only need to call it once for each UI-specific action. + UFUNCTION(BlueprintCallable) + void RegisterInterestInEnhancedInputAction(const UInputAction* Action, ETriggerEvent TriggerEvent); };