From 600603ce9269c10e9e08186454e74c2f3b0a6ff2 Mon Sep 17 00:00:00 2001 From: Steve Streeting Date: Thu, 3 Nov 2022 12:18:34 +0000 Subject: [PATCH] Fix #6: Change InputImage update delay to a tickable Previously used a timer but timers cannot run while game is paused, and UI images should update regardless. --- .../Private/StevesUI/InputImage.cpp | 49 ++++++++++++++++--- .../Public/StevesUI/InputImage.h | 20 ++++++-- 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/Source/StevesUEHelpers/Private/StevesUI/InputImage.cpp b/Source/StevesUEHelpers/Private/StevesUI/InputImage.cpp index 68db7be..5291725 100644 --- a/Source/StevesUEHelpers/Private/StevesUI/InputImage.cpp +++ b/Source/StevesUEHelpers/Private/StevesUI/InputImage.cpp @@ -107,15 +107,50 @@ void UInputImage::UpdateImage() SetBrushFromAtlasInterface(Sprite, true); } } - DelayedUpdateImageTimer.Invalidate(); + bIsDirty = false; + DelayUpdate = 0; } void UInputImage::MarkImageDirty() { - if (!DelayedUpdateImageTimer.IsValid()) - { - // Delayed update - GetWorld()->GetTimerManager().SetTimer(DelayedUpdateImageTimer, this, &UInputImage::UpdateImage, 0.5f); - } - + bIsDirty = true; + DelayUpdate = 0.5f; } + +// Tickables +// We need a tick rather than FTimer because timers won't run when game is paused, and UIs are useful while paused! +ETickableTickType UInputImage::GetTickableTickType() const +{ + return ETickableTickType::Conditional; +} +bool UInputImage::IsTickableWhenPaused() const +{ + // UIs need to update while game is paused + return true; +} +bool UInputImage::IsTickableInEditor() const +{ + return false; +} + +bool UInputImage::IsTickable() const +{ + // Only need to tick while dirty + return bIsDirty; +} + +void UInputImage::Tick(float DeltaTime) +{ + DelayUpdate -= DeltaTime; + if (DelayUpdate <= 0) + { + UpdateImage(); + } +} + +TStatId UInputImage::GetStatId() const +{ + RETURN_QUICK_DECLARE_CYCLE_STAT( UInputImage, STATGROUP_Tickables ); +} + +// Tickables diff --git a/Source/StevesUEHelpers/Public/StevesUI/InputImage.h b/Source/StevesUEHelpers/Public/StevesUI/InputImage.h index ab77863..a30843c 100644 --- a/Source/StevesUEHelpers/Public/StevesUI/InputImage.h +++ b/Source/StevesUEHelpers/Public/StevesUI/InputImage.h @@ -10,7 +10,7 @@ /// A special widget containing an image which populates itself based on an input action / axis and can dynamically /// change based on the active input method. UCLASS() -class STEVESUEHELPERS_API UInputImage : public UImage +class STEVESUEHELPERS_API UInputImage : public UImage, public FTickableGameObject { GENERATED_BODY() @@ -39,9 +39,13 @@ protected: UPROPERTY(EditAnywhere) UUiTheme* CustomTheme; - bool bSubbedToInputEvents = false; + UPROPERTY(EditAnywhere) + bool bUpdateWhilePaused = true; + + bool bSubbedToInputEvents = false; + bool bIsDirty = true; + float DelayUpdate = 0; - FTimerHandle DelayedUpdateImageTimer; public: /// Tell this image to display the bound action for the current input method @@ -76,6 +80,16 @@ public: virtual void BeginDestroy() override; virtual void SetVisibility(ESlateVisibility InVisibility) override; + + // FTickableGameObject begin + virtual void Tick(float DeltaTime) override; + virtual TStatId GetStatId() const override; + virtual bool IsTickableWhenPaused() const override; + virtual bool IsTickableInEditor() const override; + virtual bool IsTickable() const override; + virtual ETickableTickType GetTickableTickType() const override; + // FTickableGameObject end + protected: