I have a character in C++ and I want to have the C++ code set the health status on the widget without using a blueprint. At the same time I would like to keep the design for my UI, which has Dynamic materials in it and so on, in the editor. Thanks in advance.
Hello, you can simply create a class derived from UUserWidget in c++ and implement your functions in c++ or even in Blueprint/c++ with “maccro UFUNCTION”
then create a blueprint Widget derived from this class
here is an example code:
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "MyWidget.generated.h"
/**
*
*/
UCLASS()
class PLUGIN_API UMyWidget : public UUserWidget
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintNativeEvent,BlueprintCallable)
void UpdateHealth();
UFUNCTION(BlueprintCallable)
void UpdateItem();
};
Thanks. That is straightforward for implemeting the widget in C++ but how do i give it to my player character to push ipdates to the widget rather than poll per tick?
In your class character you can create a reference of your widget and the class it uses which you expose in Blueprint
here in your Character.h:
UPROPERTY()
UMyWidget* MyWidget;
UPROPERTY(BlueprintReadOnly,EditAnywhere)
TSubclassOf<UMyWidget> MyWidgetClass;
then in your cpp you can create it and do whatever you want
if(!IsValid(MyWidget))
MyWidget= CreateWidget<UMyWidget>(GetWorld()->GetFirstPlayerController(),MyWidgetClass);
if(IsValid(MyWidget))
{
MyWidget->AddToViewport();
//Do your update in your cpp
MyWidget->UpdateHealth();
MyWidget->UpdateItem();
}
in your Blueprint, just set MyWidgetClass to the widget you created in the editor.
This actually has become problematic because I cant seem to set the variables in the C++ with the blueprint.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "QCMissionHUD.generated.h"
UCLASS(Abstract)
class UQCMissionHUD : public UUserWidget {
GENERATED_BODY()
public:
/** Update the HUD with the current the shield percent. */
void SetShield(float Percent);
/** The dynamic material used to represent the shield. */
UPROPERTY(BlueprintReadWrite, meta=(BindWidget))
class UMaterialInstanceDynamic* ShieldMaterial;
};
This doesnt work. I have tried a number of things to set the dynamic material instance, using a number of events and the blueprint compiler still reports:
A required widget binding "ShieldMaterial" of type Material Instance Dynamic was not found.
Clearly I am missing somethng but deep search of the internet has not revealed what that might be.
Unfortunately I cant get this working so I will try slate.
You don’t need a “deep search” of the internet, you need to read the error message.
And, potentially, doing a shallow search of the source code.