How to do it...

  1. Create a new GameModeBase subclass called AttributeGameMode.
  2. Update the AttributeGameMode.h file to the following: 
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameStateBase.h"
#include "SlateBasics.h"
#include "AttributeGameMode.generated.h"

/**
*
*/
UCLASS()
class CHAPTER_14_API AAttributeGameMode : public AGameModeBase
{
GENERATED_BODY()

TSharedPtr<SVerticalBox> Widget;
FText GetButtonLabel() const;

public:
virtual void BeginPlay() override;

};
  1. Add the implementation for BeginPlay within the .cpp file:
void AAttributeGameMode::BeginPlay()
{
Super::BeginPlay();

Widget = SNew(SVerticalBox)
+ SVerticalBox::Slot()
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SNew(SButton)
.Content()
[
SNew(STextBlock)
.Text(TAttribute<FText>::Create(TAttribute<FText>::FGetter::CreateUObject(this, &AAttributeGameMode::GetButtonLabel)))
]
];
GEngine->GameViewport->AddViewportWidgetForPlayer(GetWorld()->GetFirstLocalPlayerFromController(), Widget.ToSharedRef(), 1);

}
  1. Also, add an implementation for GetButtonLabel():
FText AAttributeGameMode::GetButtonLabel() const
{
FVector ActorLocation = GetWorld()->GetFirstPlayerController()->GetPawn()->GetActorLocation();
return FText::FromString(FString::Printf(TEXT("%f, %f, %f"), ActorLocation.X, ActorLocation.Y, ActorLocation.Z));
}
  1. Compile your code and launch the editor.
  2. Override the game mode in World Settings to be AAttributeGameMode.
  1. Note that, in a Play In Editor session, the value on the UI's button changes as the player moves around the scene: