Widget C++

Hi, I can’t get the button to appear on the screen.
In a new C++ project, I created a Blueprint widget with one button.

1

Then I created a new C++ widget class and made it the parent of the Blueprint Widget.

Then I wrote this code
GameModeBase.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "Project_WidgetGameModeBase.generated.h"

/**
 * 
 */
UCLASS()
class PROJECT_WIDGET_API AProject_WidgetGameModeBase : public AGameModeBase
{
	GENERATED_BODY()
	
protected:
    /** Called when the game starts. */
    virtual void BeginPlay() override;

    /** The widget class we will use as our menu when the game starts. */
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UMG Game")
        TSubclassOf<UUserWidget> WidgetClass;

    /** The widget instance that we are using as our menu. */
    UPROPERTY()
        class UMyWidget* MyWidget;
};

GameModeBase.cpp

#include "Project_WidgetGameModeBase.h"
#include "MyWidget.h"
#include "Blueprint/UserWidget.h"

void AProject_WidgetGameModeBase::BeginPlay()
{
    Super::BeginPlay();

    if (IsValid(WidgetClass))
    {
        MyWidget = Cast<UMyWidget>(CreateWidget(GetWorld(), WidgetClass));

        if (MyWidget != nullptr)
        {
            MyWidget->AddToViewport();
        }
    }
}

The button does not appear on my screen. What’s the problem here?

I already figured it out and the following question arose.
In a new C++ project I created the character Cube. The cube has two public variables.

Cube.cpp

// Sets default values
ACube::ACube()
{
 	// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you dont need it.
	PrimaryActorTick.bCanEverTick = true;

	static ConstructorHelpers::FObjectFinder<UStaticMesh>C(TEXT("StaticMesh'/Game/StarterContent/Shapes/Shape_Cube.Shape_Cube'"));

	UStaticMeshComponent* Cube = CreateDefaultSubobject<UStaticMeshComponent>("Cube");
	Cube->SetupAttachment(RootComponent);
	Cube->SetStaticMesh(C.Object);

	MaxHealth = 200.f;
}

// Called every frame
void ACube::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	Health = rand() % 100 + 50.f;
}

I also created a C++ class Widget consisting of one health bar.

HealthBar.h

#pragma once

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "HealthBar.generated.h"

UCLASS()
class CUBEHEALTH_API UHealthBar : public UUserWidget
{
	GENERATED_BODY()
	
protected:
	UPROPERTY(BlueprintReadWrite, meta = (BindWidget))
		class UProgressBar* Bar;
};

I got the following result.

I need the health bar to correspond to the value of the Health variable, which is constantly changing. How to do this in C++?

The “cleanest” way to do this ( IMO ) is using the ViewModel:

https://docs.unrealengine.com/5.3/en-US/umg-viewmodel/

1 Like

What’s the difference? I just need to assign the result of dividing two numbers to a variable.
Bar = Health/MaxHealth.
Here I am writing this code

HealthBar.cpp

#include "HealthBar.h"
#include "Components/ProgressBar.h"

void UHealthBar::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
	Super::NativeTick(MyGeometry, InDeltaTime);

	Bar->SetPercent(0.9f);
}

This doesn’t work, my health bar doesn’t set to 0.9.

What’s the difference?

If your project grows, this would make it easier to maintain.

I just need to assign the result of dividing two numbers to a variable.

Is your Widget Blueprint inheriting from your class? Does the Progress Bar have the same name ‘Bar’?

You can change the Parent Class in your Widget Blueprint > Graph > Class Settings > ( Details ) Parent Class.

I need the health bar to correspond to the value of the Health variable, which is constantly changing. How to do this in C++?

The easiest way would be for you:

  1. Create the UserWidget in C++.
  2. Store the variable created by the function.
  3. Create a public function in UHealthBar to set the progress value.
  4. Call this function from your other class.

I don’t have examples in C++, before I did, but now I find it easier to leave the visual part in Blueprint.

Creating User Widget:
https://docs.unrealengine.com/4.27/en-US/API/Runtime/UMG/Blueprint/CreateWidget/

You need to store the variable returning from this function ( C++ or Blueprint ) to change its values.

Example:
https://forums.unrealengine.com/t/createwidget-c/462559/2

1 Like