I am trying to make health and stamina bars that lengthen as the player levels up. Anyone know how I can change the horizontal size of a progress bar at runtime? (not its fill percentage) Or if a progress bar isn’t the way to go about it?
I’m working in C++ do you know the classes these are derived from?
header
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "Components/ProgressBar.h"
#include "Components/CanvasPanelSlot.h"
#include "MyUserWidget.generated.h"
/**
*
*/
UCLASS(Blueprintable,BlueprintType)
class MY_API UMyUserWidget : public UUserWidget
{
GENERATED_BODY()
public:
// progress bar
UPROPERTY(BlueprintReadWrite, meta = (BindWidget))
UProgressBar* ProgBar; // <= name in widget needs to be the same
UFUNCTION(BlueprintCallable)
void SetSize(FVector2D newSize);
};
cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyUserWidget.h"
void UMyUserWidget::SetSize(FVector2D newSize)
{
UCanvasPanelSlot* CanvasSlot = Cast<UCanvasPanelSlot>(ProgBar->Slot);
CanvasSlot->SetSize(newSize);;
}
Add “UMG” to your build file
Reaction in widget
Thank you so much, what do you mean by add UMG to build file? I created the C++ class and then created a BP based on said class. Added the Event Pre Construct as you did in the first image you shared, but how and where do I see the realized widget?
Each c++ project has a file in your source directory named the same as your project name then build.cs
Inside are instructions fir the compiler how unreal must build it. Dependencies tells unreal on what modules your game depends on to run.
If you are using widgets then the are in the UMG model (look at the definition of UUserWidget in the documentation)
Your c++ based widget extends that class so you need umg
Do you mean to add “UMG” into the DependencyModuleNames.AddRange ?? And after this, is setting up this widget to reflect a character’s stamina similar to creating a default subobject?
Hello.
How to change the size of the progress bar is already shown in BP and in C++.
Note that in order to use CanvasSlot, the parent of the progress bar must be a CanvasPanel!
If it is not, you can “SetSize” it by traversing the parent of the parent, and further parents, and finally getting the widget that is a child of CanvasPanel.
The C++ classes are UCanvasPanelSlot and FAnchorData.
Need more explanation? Or help?
I think Anchors and Slots in the UMG UI Designer Guide might be helpful.
Thanks.
Yes you need to add it after “InputCore”
Then create a class based on UUserWidget and use the BindWidget meta like I showed you in the previous post to get the c++ progresss bar.
Then you will have a c++ version of the progress bar that can be accessed from the character. During the stamina drain / regen process you can access the progress bar directly if needed as well as setting it’s size via the canvas slot function.
Do I need to declare an instance of the widget on my character? I added UMG to the build file, but it’s not drawing to the screen ofc and I don’t know how to go about that. Also when I click open my blueprint based on the C++ class there is only an event graph no visual element.
Even if the class is pure c++ if it is based on UUserWidget you should have a designer graph for it.
For the set size function to work it needs the element to exist inside of the user widget and follow the same name as the bind name and needs to be set as a variable.
So far I don’t see any variables in your widget.
Did you remember to add the bind widget meta on the progress bar uproperty?
UPROPERTY(BlueprintReadWrite, meta = (BindWidget))
Normally if you have a bindwidget that is not set to optional, then a compile will cause an error message saying that the object is missing in the widget.
If I may add, when I create a BP that inherits from UMyUserWidget, the blueprint type is “WidgetBlueprint” (when I open it, there is a Designer tab and a Graph tab).
Then I will get the following error
A required widget binding “ProgBar” of type Progress Bar was not found.
Now, add a progress bar as a child of CanvasPanel, name the progress bar ProgBar, and do the UI design work.
Once compiled, the error is resolved and the progress bar can be accessed with the name ProgBar.
This is also true for other properties that use the “BindWidget” meta.
Yes I have it declared like so in my player character’s header file. I’ve gotten no errors and have seen no effect
You can’t use meta BindWidget on the widget itself. It has to be INSIDE of the widget to work.
You can assign the progress bar inside of the widget the uproperty meta.
If you want to change the size of the widget on the character then you need to set it’s size in the widget component.
Or through BP
Just put the needed values and not 0,0
So it’s more of a problem of miscommunication of what is needed.
You can either change the progress bar size through the bindwidget meta or control the whole widget itself via set draw size.
The following is a description of Widget.h
// [PropertyMetadata] This property requires a widget be bound to it in the designer. Allows easy native access to designer defined controls.
// UPROPERTY(meta=(BindWidget))
BindWidget,
BindWidget is available in a limited number of locations
To change only the size of the progress bar, give UStaminaWidget the UProgressBar* property and write the specifier UPROPERTY(BlueprintReadWrite, meta = (BindWidget))
as follows.
UPROPERTY(BlueprintReadWrite, meta = (BindWidget))
UProgressBar* StaminaBar;
Then resize it using UCanvasPanelSlot.
void UStaminaWidget::SetStaminaBarSize(FVector2D DesiredSize)
{
UCanvasPanelSlot* CanvasSlot = Cast<UCanvasPanelSlot>(StaminaBar->Slot);
if (CanvasSlot)
{
CanvasSlot->SetSize(DesiredSize);
}
}
I added that macro because I misunderstood your response making sure I had it. But I did already have it in the widget component as well. This is what I’ve had since you first initially explained it to me the other day.
.cpp
.h
It definitely is a communication issue, I really don’t understand how this is supposed to work from this point forward. I don’t need an instance of my StaminaWidget on my character? You’re saying I just call SetSize without one because it’s public? But I’d still need a pointer to it right? And before I can even change its size, I’m not even getting it drawn to the screen at all.
Before the UI can be displayed, UI design work must be done.
The same is true if you create a class in C++ that inherits from the UserWidget class, and some people use a means called Slate, but here we will assume the UMG designer functionality.
First, add Blueprintable, BlueprintType
to the UCLASS specifier to allow blueprint inheritance
UCLASS(Blueprintable, BlueprintType)
class _API UStaminaWidget : public UUserWidget
Next, create a Widget with UStaminaWidget as its parent by creating a new Blueprint in Content Browser.
Then, as shown in the previous replies, resolve the errors and design the UI.
When you try to display it, you need an instance, the class is on the BP side, so from C++, you can figure out the actual class with TSubClassOf (then set it on the BP side).
For a simple example, if you want to use it in a character’s WidgetComponent, you can pass it in with SetWidget or SetWidgetClass on the BP side.
StaminaCPP.zip (48.4 KB)
Full project that has all parts in c++.
You could extract stats to a separate actor class to clean it in the final project, but it’s just a proof of concept.
After adding
Just make sure the progress bar isn’t nested inside of a container that will restrict it’s size automatically (cast will then fail)