From 0c92bcbaa81f143925aa2a796167e8b1cae63e41 Mon Sep 17 00:00:00 2001 From: Steve Streeting Date: Tue, 11 Apr 2023 12:24:07 +0100 Subject: [PATCH 1/3] Fix typewriter text size calculation being wrong just after first construction --- .../Private/StevesUI/TypewriterTextWidget.cpp | 43 ++++++++++++++++--- .../Public/StevesUI/TypewriterTextWidget.h | 4 ++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/Source/StevesUEHelpers/Private/StevesUI/TypewriterTextWidget.cpp b/Source/StevesUEHelpers/Private/StevesUI/TypewriterTextWidget.cpp index 26813a7..f79cd2e 100644 --- a/Source/StevesUEHelpers/Private/StevesUI/TypewriterTextWidget.cpp +++ b/Source/StevesUEHelpers/Private/StevesUI/TypewriterTextWidget.cpp @@ -110,17 +110,39 @@ void UTypewriterTextWidget::PlayLine(const FText& InLine, float Speed) bHasFinishedPlaying = false; LineText->SetText(FText()); - CalculateWrappedString(); - - FTimerDelegate Delegate; - Delegate.BindUObject(this, &ThisClass::PlayNextLetter); - TimerManager.SetTimer(LetterTimer, Delegate, LetterPlayTime/CurrentPlaySpeed, true); - - SetVisibility(ESlateVisibility::SelfHitTestInvisible); + if (bFirstPlayLine) + { + // Delay the very first PlayLine after construction, CalculateWrappedString is not reliable until a couple + // of UI geometry updates. At first the geometry is 0, then it's just wrong, and then finally it settles. + FTimerHandle TempHandle; + FTimerDelegate DelayDelegate; + DelayDelegate.BindUObject(this, &ThisClass::StartPlayLine); + TimerManager.SetTimer(TempHandle, DelayDelegate, 0.2f, false); + } + else + { + StartPlayLine(); + } } } +void UTypewriterTextWidget::StartPlayLine() +{ + CalculateWrappedString(); + + FTimerDelegate Delegate; + Delegate.BindUObject(this, &ThisClass::PlayNextLetter); + + FTimerManager& TimerManager = GetWorld()->GetTimerManager(); + TimerManager.SetTimer(LetterTimer, Delegate, LetterPlayTime/CurrentPlaySpeed, true); + + SetVisibility(ESlateVisibility::SelfHitTestInvisible); + + bFirstPlayLine = false; + +} + void UTypewriterTextWidget::SkipToLineEnd() { FTimerManager& TimerManager = GetWorld()->GetTimerManager(); @@ -137,6 +159,13 @@ void UTypewriterTextWidget::SkipToLineEnd() OnLineFinishedPlaying(); } +void UTypewriterTextWidget::NativeConstruct() +{ + Super::NativeConstruct(); + + bFirstPlayLine = true; +} + void UTypewriterTextWidget::PlayNextLetter() { // Incorporate pauses as a multiple of play timer (may not be exact but close enough) diff --git a/Source/StevesUEHelpers/Public/StevesUI/TypewriterTextWidget.h b/Source/StevesUEHelpers/Public/StevesUI/TypewriterTextWidget.h index b090c78..e7e5815 100644 --- a/Source/StevesUEHelpers/Public/StevesUI/TypewriterTextWidget.h +++ b/Source/StevesUEHelpers/Public/StevesUI/TypewriterTextWidget.h @@ -109,6 +109,8 @@ public: const FString& GetCurrentRunName() const { return CurrentRunName; } protected: + virtual void NativeConstruct() override; + /// Called when on or more letters are added, if subclasses want to override UFUNCTION(BlueprintImplementableEvent, Category = "Typewriter") void OnPlayLetter(); @@ -128,6 +130,7 @@ private: void CalculateWrappedString(); FString CalculateSegments(FString* OutCurrentRunName); + void StartPlayLine(); UPROPERTY() FText CurrentLine; @@ -159,4 +162,5 @@ private: FTimerHandle LetterTimer; float CurrentPlaySpeed = 1; float PauseTime = 0; + bool bFirstPlayLine = true; }; \ No newline at end of file From 616daac1a631c7e6bfa89ba3c3fe3a47e4032647 Mon Sep 17 00:00:00 2001 From: Steve Streeting Date: Tue, 11 Apr 2023 13:08:28 +0100 Subject: [PATCH 2/3] Remove unnecessary (and unsafe) set --- .../StevesUEHelpers/Private/StevesUI/TypewriterTextWidget.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Source/StevesUEHelpers/Private/StevesUI/TypewriterTextWidget.cpp b/Source/StevesUEHelpers/Private/StevesUI/TypewriterTextWidget.cpp index f79cd2e..cf6f2cd 100644 --- a/Source/StevesUEHelpers/Private/StevesUI/TypewriterTextWidget.cpp +++ b/Source/StevesUEHelpers/Private/StevesUI/TypewriterTextWidget.cpp @@ -109,8 +109,6 @@ void UTypewriterTextWidget::PlayLine(const FText& InLine, float Speed) bHasFinishedPlaying = false; - LineText->SetText(FText()); - if (bFirstPlayLine) { // Delay the very first PlayLine after construction, CalculateWrappedString is not reliable until a couple From 7a5bb9d58192cceab93aca9af1910d09cfe0a8c9 Mon Sep 17 00:00:00 2001 From: Steve Streeting Date: Tue, 11 Apr 2023 13:08:56 +0100 Subject: [PATCH 3/3] Fix brief display of full line before first letter callback --- .../StevesUEHelpers/Private/StevesUI/TypewriterTextWidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/StevesUEHelpers/Private/StevesUI/TypewriterTextWidget.cpp b/Source/StevesUEHelpers/Private/StevesUI/TypewriterTextWidget.cpp index cf6f2cd..45a28f2 100644 --- a/Source/StevesUEHelpers/Private/StevesUI/TypewriterTextWidget.cpp +++ b/Source/StevesUEHelpers/Private/StevesUI/TypewriterTextWidget.cpp @@ -138,6 +138,8 @@ void UTypewriterTextWidget::StartPlayLine() SetVisibility(ESlateVisibility::SelfHitTestInvisible); bFirstPlayLine = false; + + PlayNextLetter(); }