1
void ACountdown::UpdateTimerDisplay()
{
CountdownText->SetText(FString::FromInt(FMath::Max(CountdownTime, 0)));
}

And,

void ACountdown::CountdownHasFinished()
{
CountdownText->SetText(TEXT("Go!"));
}

This is an example of a countdown where the text 3, 2, 1 Go! is printed after the game starts. However...Error message were printed in the two parts above. (FString::FromInt and TEXT)

The error message is as follows.

Error (active) E0312 no suitable user-defined conversion from "FString" to "const FText" exists

Error (active) E0415 no suitable constructor exists to convert from "const wchar_t [4]" to "FText"

Error C2664 'void UTextRenderComponent::SetText(const FText &)': cannot convert argument 1 from 'FString' to 'const FText &'

Error C2664 'void UTextRenderComponent::SetText(const FText &)': cannot convert argument 1 from 'const wchar_t [4]' to 'const FText &'


I wrote the whole code at the bottom. I was following the example below. I practiced the examples of Variables, Timers, and Events below.
(https://docs.unrealengine.com/5.0/en-US/quick-start-guide-to-variables-timers-and-events-in-unreal-engine-cpp/)

Did I forget about the header file? I'm at Countdown.cpp

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/TextRenderComponent.h"
#include "Countdown.generated.h"

at Countdown.h

#include "Components/TextRenderComponent.h"
#include "Countdown.h"

I'm just guessing there's something missing in the notation of the string. I rewrote the code more than five times because I'm afraid I made a mistake. But nothing has changed. Is there something that works on UE4 but not on UE5? How can I fix this?

Thank you for reading it.

it is Countdown.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/TextRenderComponent.h"
#include "Countdown.generated.h"

UCLASS()
class MYPROJECT_API ACountdown : public AActor
{
GENERATED_BODY()

public: 
ACountdown();

protected:
virtual void BeginPlay() override;

public: 

virtual void Tick(float DeltaTime) override;

int32 CountdownTime;

UTextRenderComponent* CountdownText;

void UpdateTimerDisplay();

void AdvanceTimer();

void CountdownHasFinished();

FTimerHandle CountdownTimerHandle;

};

and Countdown.cpp #pragma once

#include "Components/TextRenderComponent.h"
#include "Countdown.h"

ACountdown::ACountdown()
{
PrimaryActorTick.bCanEverTick = false;

CountdownText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("CountdownNumber"));
CountdownText->SetHorizontalAlignment(EHTA_Center);
CountdownText->SetWorldSize(150.0f);
RootComponent = CountdownText;

CountdownTime = 3;
}

void ACountdown::BeginPlay()
{
Super::BeginPlay();

UpdateTimerDisplay();
GetWorldTimerManager().SetTimer(CountdownTimerHandle, this, &ACountdown::AdvanceTimer, 1.0f, true);
}

void ACountdown::UpdateTimerDisplay()
{
CountdownText->SetText(FString::FromInt(FMath::Max(CountdownTime, 0)));
}

void ACountdown::AdvanceTimer()
{
--CountdownTime;
UpdateTimerDisplay();

if (CountdownTime < 1)
{
GetWorldTimerManager().ClearTimer(CountdownTimerHandle);
CountdownHasFinished();
}
}

void ACountdown::CountdownHasFinished()
{
CountdownText->SetText(TEXT("Go!"));
}
DY.Kim
  • 11
  • 4
  • 1
    What do you mean red line at the bottom? is there any error message? – liorko Oct 08 '22 at 18:41
  • Please see [ask] and [mre]. I should be able to understand the gist on your question after reading the first paragraph, and the code in your question should be trimmed down. But don't trim too much -- I should be able to copy the code block(s) from your question, compile that code and reproduce your result. – JaMiT Oct 08 '22 at 18:45
  • I tried to improve it as you said. Thank you – DY.Kim Oct 08 '22 at 18:54
  • 1
    *"Error message were printed in the two parts above"* - what errors? Your question needs to include the exact error messages – UnholySheep Oct 08 '22 at 18:54
  • We can't do anything without the error message(s). – Etienne de Martel Oct 08 '22 at 19:05
  • I have added an error message to the body of the article. I'm sorry and thank you. – DY.Kim Oct 08 '22 at 19:09
  • @DY.Kim I have been having the same exact error. First I had an error that `RootComponent = CountdownText` has “no operator ‘=‘ that matches these operands”. Then out of nowhere it randomly switches to the error you have now. And for me. It’s the only one, FString to FromInt. I’m not sure what is going on with this tutorial but until I got to this one it’s been throwing so many random errors. Maybe this one isn’t updated enough to work in UE5. – Angel Baby Oct 11 '22 at 02:19

2 Answers2

2

I second what ken wrote: You are trying to pass an FString where an FText is required. But since you are coming from an int, you could use FText::AsNumber.

CountdownText->SetText(FText::AsNumber(FMath::Max(CountdownTime, 0)));

You should research the differences between the three types of text representation in unreal FName, FString and FText.

FName is internally a number in a lookup table, so you can copy it without actually copying a string. Also comparison is identical to just comparing two integers (because, that's what actually happens). There are some downsides: FName ignores whitespace and is case insensitive.

FString is your good old string, similar to std::string. It stores an array of char and an int denoting it's length. Comparing it is tedious and copying expensive. But it's flexible and can easily be extended.

FText is used for localization. Internally, it is similar to FName, consisting of a reference to a string somewhere else, but it is at the same time localization agnostic. It also provides formatting options that are also localization agnostic (e.g. gender and count related changes in sentences).

Now, UI always uses FText, because it makes it easy to swap strings between languages. Object identifiers are always FName, because it allows them to be uniquely identifiable. You have to know how to convert these three types of "strings" into each other, to use them effectively.


Note about the TEXT() macro: It is used to convert a platform const char* into a const wchar_t*, so essentially makes sure that the input is in the correct format that unreal uses to represent characters internally. You can use this, to make FString instances, because FString implicitly allows this. FText does not.

If you want to create an FText out of a string literal, you have two options:

  1. Create localizable text. This can be done by using LOCTEXT() or NSLOCTEXT() based on if you have defined LOCTEXT_NAMESPACE in your file.
  2. Create an invariant text using INVTEXT(). It's not used by the localizer, and is essentially a shorthand for FText::FromString(TEXT()). (It's not identical, but it feels identical to you as a programmer).
Max Play
  • 3,717
  • 1
  • 22
  • 39
  • Thank you for the good explanation. Maybe I should learn the basics first, not follow the example. I understood that in order to output characters from the UE, it must go through a conversion step, but most of them are very difficult to understand. As you answered, I used FText::AsNumber `void ACountdown::CountdownHasFinished(){CountdownText->SetText(TEXT("Go!"));}` An error message appears pointing to **TEXT**// **Error (active) E0415 no suitable constructor exists to convert from "const wchar_t [4]"** – DY.Kim Oct 18 '22 at 18:32
  • TEXT is just a macro. If you want to have an FText out of a const char*, use INVTEXT() or LOCTEXT(). See my post for links to the docs. – Max Play Oct 19 '22 at 11:29
  • I think it will take a little more time for me as a Beginner to understand the answers you've given me. I don't know why it's so hard to learn the tutorial from UE homepage. When I installed **UE4** and followed it, there was no error in TEXT! Maybe it doesn't work easily on the UE5. I don't know what's changed, but thank you for your kindness :) – DY.Kim Oct 19 '22 at 17:12
0

You're trying to set an FString instead of an FText, which you can't do. To set an FText, you use the TEXT macro or convert the FString with another method.

void ACountdown::UpdateTimerDisplay()
{
CountdownText->SetText(TEXT("%s"), FString::FromInt(FMath::Max(CountdownTime, 0)));
}
ken
  • 46
  • 4
  • Thank you. However, the error message below appears. **no suitable constructor exists to convert from "const wchar_t [3]" to "FText"** This error message also occurs in the part of function ``. I don't think I can use TEXT when I see the red underline on TEXT. – DY.Kim Oct 18 '22 at 18:41