Download

Access child components of a blueprint widget through c++

Dear community I come here in these darkest hours of mine … I’m an Unreal Engine 4 begginer and so I would like to ask for a guidance regarding c++ script accessing child components of a blueprint widget to be able to modify them.

To put this in simple words, I created a blueprint widget called “InteractWidget” and inside that I have canvas which holds an Image and a Textblock. (As shown in the picture down below)

Now what my idea behind this was that I would like to “AddToViewport” this widget through c++ while modifying the TextBlock since the key they have to press changes based on control settings… So to do that I created a quick “SphereTrigger” where I’d reference my widget blueprint as variable and then use that to access it’s child components and deal with this like so. Everything would be just fine the widget works I can show it and hide it, however I tried nearly every possible way to access that TextBlock … no success. Any help is appreciated, I will leave my code down below.

TextTrigger.h



#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TextTrigger.generated.h"

UCLASS()
class RUNNING_API ATextTrigger : public AActor
{
GENERATED_BODY()

public:
ATextTrigger();
FVector2D GetGameViewportSize();

protected:
virtual void BeginPlay() override;

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

UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidget), Category = "target")
class UUserWidget* Widget;

UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UTextBlock* IntTextBlock;

UPROPERTY(VisibleAnywhere, Category = "Text Pop-up Trigger")
FString Message;

UPROPERTY(VisibleAnywhere, Category = "Text Pop-up Trigger")
class USphereComponent* TriggerSphere;

UFUNCTION()
virtual void ToggleShow();

UFUNCTION()
void OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

UFUNCTION()
void OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

};


TextTrigger.cpp



#include "TextTrigger.h"
#include "Components/SphereComponent.h"
#include "DrawDebugHelpers.h"
#include <Runtime/Engine/Classes/Kismet/GameplayStatics.h>
#include "Components/TextBlock.h"
#include "Blueprint/UserWidget.h"


ATextTrigger::ATextTrigger()
{

try
{
PrimaryActorTick.bCanEverTick = true;

//Message
Message = FString("Default Message");

//Trigger
TriggerSphere = CreateDefaultSubobject<USphereComponent>(TEXT("Trigger Sphere Component"));
TriggerSphere->InitSphereRadius(300.f);
TriggerSphere->SetCollisionProfileName(TEXT("Trigger"));

TriggerSphere->OnComponentBeginOverlap.AddDynamic(this, &ATextTrigger::OnOverlapBegin);
TriggerSphere->OnComponentEndOverlap.AddDynamic(this, &ATextTrigger::OnOverlapEnd);
}
catch (...) {
UE_LOG(LogTemp, Error, TEXT("There was an exception when executing ATextTrigger::ATextTrigger()"));
return;
}
}

void ATextTrigger::BeginPlay()
{
try
{
Super::BeginPlay();
DrawDebugSphere(GetWorld(), GetActorLocation(), 300.f, 50, FColor::Red, true, -1, 0, 2);

if (!Widget)
throw("Nullptr");

if (!IntTextBlock)
{
UE_LOG(LogTemp, Warning, TEXT("Looking for UTextBlock"));

UWidget* block = Widget->GetWidgetFromName(TEXT("IntTextBlock"));

if (!block)
{
UE_LOG(LogTemp, Warning, TEXT("The text widget is null."));
return;
}

IntTextBlock = Cast<UTextBlock>(block);

if (!IntTextBlock)
{
UE_LOG(LogTemp, Warning, TEXT("The text widget failed to be casted to UTextBlock."));
return;
}
}

UE_LOG(LogTemp, Warning, TEXT("Found UTextBlock"));
IntTextBlock->SetText(FText::FromString(Message));

}
catch (...) {
UE_LOG(LogTemp, Error, TEXT("There was an exception when executing ATextTrigger::BeginPlay()"));
return;
}
}

void ATextTrigger::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);

}

void ATextTrigger::ToggleShow()
{
if (!Widget)
return;

if (Widget->IsInViewport())
Widget->RemoveFromViewport();
else
Widget->AddToViewport();
}

void ATextTrigger::OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
if (OtherActor && OtherActor != this && OtherComp) {
ATextTrigger::ToggleShow();
}
}

void ATextTrigger::OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
if (OtherActor && OtherActor != this && OtherComp) {
ATextTrigger::ToggleShow();
}
}

FVector2D ATextTrigger::GetGameViewportSize()
{
FVector2D Result = FVector2D(1, 1);

if (GEngine && GEngine->GameViewport)
{
GEngine->GameViewport->GetViewportSize( /*out*/Result);
}

return Result;
}