Download

Text block overlapping issue c++

Hi all, so I’m making a timer user widget in my game and I’ve got it to sort of work but every time the text updates (every second) the last text doesn’t remove so it just looks like a complete mess.

Here’s my DisplayTimeWidget code:
.h -
#pragma once

#include “CoreMinimal.h”
#include “Blueprint/UserWidget.h”
#include “DisplayTimeWidget.generated.h”

class UTextBlock;

UCLASS()
class RACETOTHEFINISH_API UDisplayTimeWidget : public UUserWidget
{
GENERATED_BODY()

public:
UDisplayTimeWidget(const FObjectInitializer& ObjectInitializer);

// Equivalent to BeginPlay
virtual void NativeConstruct() override;

UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidget))
    UTextBlock* TXTtime;

// Called to update the text so every 0.01 seconds
void UpdateTimerText();

// Time handler
FTimerHandle TimeHandle;

// Timer in seconds
float time;

};

.cpp -
#include “DisplayTimeWidget.h”
#include “Blueprint/UserWidget.h”
#include “Engine/World.h”
#include “Engine.h”
#include “Components/TextBlock.h”

#define print(text) if (GEngine) GEngine->AddOnScreenDebugMessage(-1, 1.5, FColor::Green,text)

UDisplayTimeWidget::UDisplayTimeWidget(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
time = 0.0f;
}

void UDisplayTimeWidget::NativeConstruct()
{
Super::NativeConstruct();

GetWorld()->GetTimerManager().SetTimer(TimeHandle, this, &UDisplayTimeWidget::UpdateTimerText, 1.0f, true);

}

void UDisplayTimeWidget::UpdateTimerText()
{
++time;
TXTtime->SetText(FText::FromString(FString::SanitizeFloat(time)));

}

Here’s my InGameHUD code:

.h -
#include “GameFramework/HUD.h”
#include “InGameHUD.generated.h”

class UDisplayTimeWidget;

UCLASS()
class RACETOTHEFINISH_API AInGameHUD : public AHUD
{
GENERATED_BODY()

public:
AInGameHUD();

// Called every frame
virtual void Tick(float DeltaTime) override;

// The bool that will control when the timer will start
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Timer")
    bool bShouldTimerStart; 

// Called when bShouldTimerStart gets set to true from blueprints
UFUNCTION()
    void StartTimer();

// The widget class that will display the timer on the screen
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "DisplayTimeWidget")
    TSubclassOf<UUserWidget> TimerWidgetClass;

private:
UDisplayTimeWidget* TimerWidget;

};

.cpp -
#include “InGameHUD.h”
#include “DisplayTimeWidget.h”

#include “Engine.h”

#define print(text) if (GEngine) GEngine->AddOnScreenDebugMessage(-1, 1.5, FColor::Green,text)

AInGameHUD::AInGameHUD()
{
bShouldTimerStart = false;
}

void AInGameHUD::Tick(float DeltaTime)
{
if (bShouldTimerStart)
{
StartTimer();
}
}

void AInGameHUD::StartTimer()
{
if (TimerWidgetClass)
{
TimerWidget = CreateWidget<UDisplayTimeWidget>(GetWorld(), TimerWidgetClass);

    if (TimerWidget)
    {
        TimerWidget-&gt;AddToViewport();
    }
}

}

Any help is much appreciated, thank you :slight_smile:

The problem is you’re calling StartTimer() every tick, which is creating a new TimerWidget. So, the mess you’re seeing is hundreds of TimerWidgets being added to the viewport over and over and over on top of one another. The way to fix this is instead of creating a new widget each tick, grab the one widget that should be there and simply update its text.

Thank you so much, I knew it was something small and stupid like that, shows how much I still have to learn :slight_smile: