Implemented line part playing

This commit is contained in:
lumpn 2023-04-10 18:20:51 +08:00
parent e4af81cd35
commit f0bd405cb2
2 changed files with 36 additions and 12 deletions

View File

@ -42,6 +42,7 @@ TSharedRef<SWidget> URichTextBlockForTypewriter::RebuildWidget()
UTypewriterTextWidget::UTypewriterTextWidget(const FObjectInitializer& ObjectInitializer) UTypewriterTextWidget::UTypewriterTextWidget(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer) : Super(ObjectInitializer)
{ {
bHasMoreLineParts = false;
bHasFinishedPlaying = true; bHasFinishedPlaying = true;
} }
@ -54,6 +55,7 @@ void UTypewriterTextWidget::SetText(const FText& InText)
LineText->SetText(InText); LineText->SetText(InText);
bHasMoreLineParts = false;
bHasFinishedPlaying = true; bHasFinishedPlaying = true;
} }
} }
@ -69,13 +71,19 @@ FText UTypewriterTextWidget::GetText() const
} }
void UTypewriterTextWidget::PlayLine(const FText& InLine, float Speed) void UTypewriterTextWidget::PlayLine(const FText& InLine, float Speed)
{
CurrentLine = InLine;
RemainingLinePart = CurrentLine.ToString();
PlayNextLinePart(Speed);
}
void UTypewriterTextWidget::PlayNextLinePart(float Speed)
{ {
check(GetWorld()); check(GetWorld());
FTimerManager& TimerManager = GetWorld()->GetTimerManager(); FTimerManager& TimerManager = GetWorld()->GetTimerManager();
TimerManager.ClearTimer(LetterTimer); TimerManager.ClearTimer(LetterTimer);
CurrentLine = InLine;
CurrentRunName = ""; CurrentRunName = "";
CurrentLetterIndex = 0; CurrentLetterIndex = 0;
CachedLetterIndex = 0; CachedLetterIndex = 0;
@ -87,13 +95,14 @@ void UTypewriterTextWidget::PlayLine(const FText& InLine, float Speed)
Segments.Empty(); Segments.Empty();
CachedSegmentText.Empty(); CachedSegmentText.Empty();
if (CurrentLine.IsEmpty()) if (RemainingLinePart.IsEmpty())
{ {
if (IsValid(LineText)) if (IsValid(LineText))
{ {
LineText->SetText(FText::GetEmpty()); LineText->SetText(FText::GetEmpty());
} }
bHasMoreLineParts = false;
bHasFinishedPlaying = true; bHasFinishedPlaying = true;
OnTypewriterLineFinished.Broadcast(this); OnTypewriterLineFinished.Broadcast(this);
OnLineFinishedPlaying(); OnLineFinishedPlaying();
@ -107,11 +116,12 @@ void UTypewriterTextWidget::PlayLine(const FText& InLine, float Speed)
LineText->SetText(FText::GetEmpty()); LineText->SetText(FText::GetEmpty());
} }
bHasMoreLineParts = false;
bHasFinishedPlaying = false; bHasFinishedPlaying = false;
LineText->SetText(FText()); LineText->SetText(FText());
const FString& currentLineString = CurrentLine.ToString(); const FString& currentLineString = RemainingLinePart;
CalculateWrappedString(currentLineString); CalculateWrappedString(currentLineString);
int maxLines = 3; int maxLines = 3;
@ -139,7 +149,8 @@ void UTypewriterTextWidget::PlayLine(const FText& InLine, float Speed)
int lastTerminator = currentLineString.FindLastCharByPredicate(IsSentenceTerminator, numLetters); int lastTerminator = currentLineString.FindLastCharByPredicate(IsSentenceTerminator, numLetters);
if (lastTerminator != INDEX_NONE) if (lastTerminator != INDEX_NONE)
{ {
const FString& shortenedString = currentLineString.Left(lastTerminator + 1); int count = lastTerminator + 1;
const FString& shortenedString = currentLineString.Left(count);
CurrentRunName = ""; CurrentRunName = "";
CurrentLetterIndex = 0; CurrentLetterIndex = 0;
@ -154,10 +165,8 @@ void UTypewriterTextWidget::PlayLine(const FText& InLine, float Speed)
CalculateWrappedString(shortenedString); CalculateWrappedString(shortenedString);
// TODO Jonas: Play remaining line after the shortened string. RemainingLinePart.RightInline(count);
// If this is done purely in the typewriter then advancing the dialog would bHasMoreLineParts = true;
// skip over all but the last part of the text. Alternatively advancing has
// to get rerouted to trigger a dialogue action only for the last part.
} }
} }
@ -181,9 +190,16 @@ void UTypewriterTextWidget::SkipToLineEnd()
LineText->SetText(FText::FromString(CalculateSegments(nullptr))); LineText->SetText(FText::FromString(CalculateSegments(nullptr)));
} }
bHasFinishedPlaying = true; if (bHasMoreLineParts)
OnTypewriterLineFinished.Broadcast(this); {
OnLineFinishedPlaying(); OnTypewriterLinePartFinished.Broadcast(this);
}
else
{
bHasFinishedPlaying = true;
OnTypewriterLineFinished.Broadcast(this);
OnLineFinishedPlaying();
}
} }
void UTypewriterTextWidget::PlayNextLetter() void UTypewriterTextWidget::PlayNextLetter()

View File

@ -56,6 +56,10 @@ class STEVESUEHELPERS_API UTypewriterTextWidget : public UUserWidget
public: public:
UTypewriterTextWidget(const FObjectInitializer& ObjectInitializer); UTypewriterTextWidget(const FObjectInitializer& ObjectInitializer);
/// Event called when a line part has finished playing, whether on its own or when skipped to end
UPROPERTY(BlueprintAssignable)
FOnTypewriterLineFinished OnTypewriterLinePartFinished;
/// Event called when a line has finished playing, whether on its own or when skipped to end /// Event called when a line has finished playing, whether on its own or when skipped to end
UPROPERTY(BlueprintAssignable) UPROPERTY(BlueprintAssignable)
FOnTypewriterLineFinished OnTypewriterLineFinished; FOnTypewriterLineFinished OnTypewriterLineFinished;
@ -102,6 +106,9 @@ public:
UFUNCTION(BlueprintCallable, Category = "Typewriter") UFUNCTION(BlueprintCallable, Category = "Typewriter")
bool HasFinishedPlayingLine() const { return bHasFinishedPlaying; } bool HasFinishedPlayingLine() const { return bHasFinishedPlaying; }
UFUNCTION(BlueprintCallable, Category = "Typewriter")
void PlayNextLinePart(float Speed = 1.0f);
UFUNCTION(BlueprintCallable, Category = "Typewriter") UFUNCTION(BlueprintCallable, Category = "Typewriter")
void SkipToLineEnd(); void SkipToLineEnd();
@ -132,7 +139,7 @@ private:
UPROPERTY() UPROPERTY()
FText CurrentLine; FText CurrentLine;
FString RemainingLinePart;
struct FTypewriterTextSegment struct FTypewriterTextSegment
{ {
@ -155,6 +162,7 @@ private:
float CombinedTextHeight = 0; float CombinedTextHeight = 0;
uint32 bHasFinishedPlaying : 1; uint32 bHasFinishedPlaying : 1;
uint32 bHasMoreLineParts : 1;
FTimerHandle LetterTimer; FTimerHandle LetterTimer;
float CurrentPlaySpeed = 1; float CurrentPlaySpeed = 1;