I’m trying to draw text on the screen from c++ with the following code but it gives me a Access violation reading location
void UHelpers::DisplayText(UWorld* World, FString Text, FVector2D Position, FColor TextColor)
{
/* If no position is set */
if (Position == FVector2D(-1.f, -1.f))
{
const FVector2D ViewportSize = FVector2D(GEngine->GameViewport->Viewport->GetSizeXY());
Position = FVector2D(ViewportSize.X / 2, ViewportSize.Y / 2);
}
if (GEngine->GetMediumFont())
{
UGameplayStatics::GetPlayerController(World, 0)->GetHUD()->DrawText(Text, Position, GEngine->GetMediumFont(), Position, TextColor);
}
}
I have checked all pointers and values and they all seem to passed probably to the function.
So I compeltly missed that the draw functions only works in a Draw call (like DrawHUD) and came up with the following solution for our problem.
.h
#pragma once
#include "GameFramework/HUD.h"
#include "MainHUD.generated.h"
USTRUCT(BlueprintType)
struct FDisplayString
{
GENERATED_USTRUCT_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = MOO)
FString Text;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = MOO)
FVector2D Position;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = MOO)
FColor Color;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = MOO)
UFont* Font;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = MOO)
FVector2D Scale;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = MOO)
int32 DisplayTime;
int32 StartTime;
};
/**
*
*/
UCLASS()
class MOONSHINEWORKS_API AMainHUD : public AHUD
{
GENERATED_BODY()
public:
AMainHUD(const class FObjectInitializer& PCIP);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = MOO)
UFont* Font;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = MOO)
TArray<FDisplayString> DisplayStrings;
UFUNCTION(BlueprintCallable, Category = MOOnshine)
void AddDisplayString(FDisplayString DisplayStringToAdd);
protected:
void DrawHUD() override;
virtual void Tick(float DeltaSeconds) override;
};
.cpp
#include “MOOnshineWorks.h”
#include “MainHUD.h”
AMainHUD::AMainHUD(const class FObjectInitializer& PCIP)
: Super(PCIP)
{
}
void AMainHUD::DrawHUD()
{
Super::DrawHUD();
int DisplayStringsCount = DisplayStrings.Num();
for (int i = DisplayStringsCount - 1; i >= 0; i--)
{
FDisplayString* DisplayString = &DisplayStrings[i];
FVector2D Position = FVector2D(DisplayString->Position.X, DisplayString->Position.Y + i * 20);
DrawText(DisplayString->Text, Position, Font, DisplayString->Scale, DisplayString->Color);
}
}
void AMainHUD::AddDisplayString(FDisplayString DisplayStringToAdd)
{
int32 DisplayStringsCount = DisplayStrings.Num();
for (int32 i = 0; i < DisplayStringsCount; i++)
{
if (DisplayStrings[i].Text == DisplayStringToAdd.Text)
{
return;
}
}
DisplayStringToAdd.StartTime = FDateTime::Now().ToUnixTimestamp();
DisplayStrings.Add(DisplayStringToAdd);
}
void AMainHUD::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
int DisplayStringsCount = DisplayStrings.Num();
FDateTime CurrentTime = FDateTime::Now();
for (int i = DisplayStringsCount - 1; i >= 0; i--)
{
FDisplayString* DisplayString = &DisplayStrings[i];
FVector2D Position = FVector2D(DisplayString->Position.X, DisplayString->Position.Y + i * 20);
if (DisplayString->DisplayTime == 0)
{
DisplayStrings.RemoveAt(i, 1);
}
else if (DisplayString->DisplayTime <= CurrentTime.ToUnixTimestamp() - DisplayString->StartTime)
{
DisplayStrings.RemoveAt(i, 1);
}
}
}