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:
WBP_PayRespect
is the name I gave to a visual blueprint with a messageTriggerActor
is the name of a C++ class that has an actor as its parent- 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!
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!
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:
- Use the correct API in C++ and your header file, and be careful to do so.
- 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
You can download the code here!