Download

How to call UCLASS function to set variable in C++ and use it at BP?

Hi, I’m newbie here and I had some research before posting this topic. So I am not just asking like pasting codes.

So
I got ThirdPersonMPCharacter.h/cpp which following the multiplayer tutorial in UE4 Document.

And I create a userwidget by myself

UCLASS()
class THIRDPERSONMP_API UMyUserWidget : public UUserWidget
{
	GENERATED_BODY()

public:
	UPROPERTY(BlueprintReadWrite, Category=CPP)
	float HP;

	void setHP(float currentHP);

and function setHP is like below :

void UMyUserWidget::setHP(float currentHP)
{
	HP = currentHP;
}

So What I want to do is…

When my character from ThirdPersonMPCharacter.cpp change variable CurrentHealth. Then I am trying to call void setHP from UMyUserWidget and set value of HP inside UMyUserWidget. Where I can handle value HP sync with ThirdPersonCharacter’s CurrentHealth. And finally using HP variable at UE4 Editor’s BP to showing(Add viewport) changing HP value.

void AThirdPersonMPCharacter::SetCurrentHealth(float healthValue)
{
	UE_LOG(LogTemp, Log, TEXT("SET_CURRENT_HEALTH , PARAM = %f"), healthValue);
	if (GetLocalRole() == ROLE_Authority)
	{
		UE_LOG(LogTemp, Log, TEXT("CURRENT_HEALTH IS CHANGING"));
		CurrentHealth = FMath::Clamp(healthValue, 0.f, MaxHealth);

		// Here is what I want... But really don't know how and this code is error.
		UMyUserWidget* MyUserWidget = Cast<UMyUserWidget>(GetClass());
		MyUserWidget->setHP(CurrentHealth);

	}
}

I got Unhandled Exception: EXCEPTION_ACCESS_VIOLATION writing address 0x00000000000003f8
PLEASE HELP. Thanks

That unhandled exception means that you tried to do something with a NULL object. That basically never happens when going from Blueprint, because Blueprint verifies object references before calling functions, so this is likely a bug somewhere in your C++ code.

Run the code in the debugger and see where the exception happens, that should show you on the stack why the object pointer is null.

I tried not running HP = currentHP; in setHP function and just UE_LOG parameter currentHP. It works fine. But when I trying to assign value to HP I got Unhandled Exception

Yes, because your UMyUserWidget pointer is NULL.

Note that it’s perfectly possible to run a method inside a class when the object pointer is NULL, as long as you don’t reference any members (explicitly or implicitly.)

But calling setHP is working fine. And UE_LOG is showing right parameter.

void UMyUserWidget::setHP(float currentHP)
{
	UE_LOG(LogTemp, Log, TEXT("setHP called. Params = %f"), currentHP);
}

So is it really about object pointer ?

Here is my MyUserWidget.h

#pragma once

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

/**
 * 
 */
UCLASS()
class THIRDPERSONMP_API UMyUserWidget : public UUserWidget
{
	GENERATED_BODY()

public:
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=CPP)
	float HP;

	void setHP(float currentHP);

protected:
	virtual void NativeConstruct() override;

	UPROPERTY(Meta=(BindWidget))
	class UCanvasPanel* CanvasPanel_1;

	UPROPERTY(Meta=(BindWidget))
	class UTextBlock* TextBlock_1;
};

And MyUserWidget.cpp

#include "MyUserWidget.h"

void UMyUserWidget::setHP(float currentHP)
{
	UE_LOG(LogTemp, Log, TEXT("setHP called. Params = %f"), currentHP);
	//HP = currentHP;
}

void UMyUserWidget::NativeConstruct()
{
	Super::NativeConstruct();
}

Try running it with debugger and see where the crash is taking place.

I am confused as how GetClass() within the AThirdPersonMPCharacter can return a UUserWidget.

do a simple if check after using Cast and see if the MyUserWidget is valid or not (Use IsValid()).

I have checked it return nullptr. But I don’t know why my function is running.
So additional question is How to cast UserWidget ? don’t know how to get Object of my custom UUserWidget Class.

What to pass at “Cast<>( ??? )”

Not sure what’s going on here, but at some point you have to create your widget:

	UMyWidget* widget = CreateWidget<UMyWidget>(...);

Right after this, check the validation of widget.

You will need to create widget first, also add it to viewport as well so you can see it in-game later on.

UMyUserWidget* MyWidget = CreateWiget<UMyUserWidget>(para1, para2);
MyWidget->AddToViewport();

Now you can use setHP() function.

casting would be needed if lets say you created your widgets in a new AHUD class then you would need to get the HUD from player Controller and cast it to yourHUD class. Easy way to remember is casting filters your datatype and returns if the datatype is Of type or not.

my personal preference is i do all the Widget related stuff in Blueprints and if i need to update anything i simply do a Multicast Delegate broadcast()

1 Like