How To Display Visual Blueprint Widget in C++ using drop-down Menu

Display widgets using C++ with a drop-down menu for choosing your custom widget in Unreal Engine 4.27

Prerequisites:

  • Unreal Engine 4.27
  • Visual Studio 2022
  • C++ plugins for Unreal Engine
  • .NET 3.1 (the newest version)

Final Result:

A widget category actor will additionally have a dropdown menu option for the widget displayed in the information panel.

Step-by-Step:

Create a C++ class from the menu once everything is set up and working.

Since I only need to display the widget when it collides with me as a pawn, I chose the Actor class as the parent. I require the following:

  1. WBP_PayRespect is the name I gave to a visual blueprint with a message
  2. TriggerActor is the name of a C++ class that has an actor as its parent
  3. Have fun!

It will lead to issues later if I explicitly state in C++ what blueprint needs to be shown on the screen. Why are you asking? It would be more difficult to debug because the application would show that message on the screen. From the drop-down option, I may select WBP to insert a blueprint class into the game world.

Let’s begin!

In the new C++ class, I need to define a capsule component that helps me detect overlapping. So in the header file, I define the capsule component name as CapsuleComp.

I must initialize CapsuleComp at the start of the C++ file.

Using the shortcuts CTRL + S to save and CTRL + ALT + F11 to code live.

After recompilation is complete, I need to create a lesson plan for a particular kid’s class.

Click with the right mouse button while selecting the newly created class. You can create a new class by selecting the option to "Create Blueprint class based on name class” from the menu, saving it in a different folder, and giving it a meaningful name.

You can see an actor by the name of CapsuleComp if you open the most recent blueprint class! Hooray! Getting closer to showing WBP!

note:
The next step was difficult, it took me a few days to find the solution.
So here it is. 😀

I had to create a pointer to the UserWidget class in order to define a widget. After investigating forums and Google, I discovered a solution that involved making a pointer in the public portion and a subclass of UUserWidget in the private section.

to provide the option of a drop-down menu CreateDefaultSubObjectUUserWidget>(TEXT="Widget")); is a line of C++ code that I used to build a drop-down menu with options. It is located inside the constructor.

I currently have options relating to the User Widget class in a drop-down menu; in order to display them, I need… YES! CapsuleComp, you rock!

note:
OVERLAPPING
As far as I know, I usually use blueprint classes with only two functions: OnActorBeginOverlap and EndOverlap.

OnActorBeginOverlap and EndOverlap

What parameters does she need, and how many arguments do functions need? The best course of action is to be aware of who overlaps with whom.

For instance, in shooter games, adversaries are hit by multiple shots until their health is reduced to zero.

The C++ class will overlap with another actor in this scenario.

Our functions should be defined in the header file. Because I don’t need a return value, I utilized the void function in the public area. Naturally, Google is your friend, so in essence, it’s copy and paste.

Re-compile your program once more, then pick your widget from a drop-down menu and attempt to play!

Troubleshooting

Here are a few recommendations if you simply copy and paste a code:

  1. Use the correct API in C++ and your header file, and be careful to do so.
  2. When developing with UMG make sure that the settings in ProjectName.Build.cs have the correct values.

Code

Trigger actor.h file

#pragma once

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

#include "TriggerActor.generated.h"


UCLASS()
class BUILDINGTEST_API ATriggerActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ATriggerActor();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

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

	//Making a subclass of UUserWidget
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Widget")
		TSubclassOf<class UUserWidget> bpPayRespectClass;

private:
	//Capsule Component is for collisions with other acotors
	UPROPERTY(VisibleAnywhere, Category = "Widget", Meta = (AllowPrivateAccess = true))
		class UCapsuleComponent* CapsuleComp;

	//Define name for widget
	UUserWidget* PayRespect;

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

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

TriggerActor CPP file

#include "TriggerActor.h"
#include "Blueprint/UserWidget.h"
#include "Components/CapsuleComponent.h"
#include "Components/StaticMeshComponent.h"
#include "Kismet/GameplayStatics.h"


// Sets default values
ATriggerActor::ATriggerActor()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	CapsuleComp = CreateDefaultSubobject<UCapsuleComponent>(TEXT("Capsule Component"));

	PayRespect = CreateDefaultSubobject<UUserWidget>(TEXT("Widget"));
	
}

// Called when the game starts or when spawned
void ATriggerActor::BeginPlay()
{
	Super::BeginPlay();
	
	CapsuleComp->OnComponentBeginOverlap.AddDynamic(this, &ATriggerActor::OnOverlapBegin);
	CapsuleComp->OnComponentEndOverlap.AddDynamic(this, &ATriggerActor::OnOverlapEnd);
}

// Called every frame
void ATriggerActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}

void ATriggerActor::OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	if (OtherActor && (OtherActor != this))
	{
		UE_LOG(LogTemp, Warning, TEXT("HITING something"));

		if (IsValid(bpPayRespectClass))		
		{
			PayRespect = CreateWidget<UUserWidget>(GetWorld(), bpPayRespectClass);
			PayRespect->AddToViewport();		
		}
	}
}

void ATriggerActor::OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	UE_LOG(LogTemp, Warning, TEXT("END overlap"));

	if (IsValid(bpPayRespectClass))
	{
		PayRespect->SetVisibility(ESlateVisibility::Hidden);
	}
}

Download code


Posted

in

,

by