UE4 C++ Class Object Variables Doesnt Update

I have two classes (AActor and UUserWidget), I have an Actor Object instance in the Widget class, and when I pickup that actor in game, I change a boolean value from false to true. The Widget class checks every tick if the bool is true or not, and if it is true then it runs a function.

The problem is, that the bool value NEVER updates in the Widget class, it does change in the Actor class, but it stays false in the Widget class.

AActor, changing the bool to true:

void ACPP_InteractBase::Pickup(){
    GEngine->AddOnScreenDebugMessage(-1,5.f,FColor::Orange,FString::Printf(TEXT("+ %s"),(*ItemInfo.Name.ToString())));
	bItemPickedUp = true;
	Destroy();
}

UUserWidget, calling the function if bItemPickedUp is true:

	if(InteractBase != nullptr){
		if(InteractBase->bItemPickedUp){
            GEngine->AddOnScreenDebugMessage(-1,5.f,FColor::Orange,FString::Printf(TEXT("InteractBase->bItemPickedUp")));
            UpdateInventoryBarSlot();
		}
	}

I tried using UPROPERTY() on every variable, but it changed nothing.
Here is how the object is created in UUserWidget:

    InteractBase = NewObject<ACPP_InteractBase>(this, InteractBaseClass);

What could be the problem? Im trying to make this work for hours now, and still nothing.

You’re destroying the instance of the actor in which you’re setting the bool.
You’re creating another instance in the widget.
These are two separate instances.

I tried commenting the Destroy() but it didnt do anything. How could I have that instance in the Widget class that Im changing in AActor class?

You don’t really need to?..
You’re only creating and instance in the widget when you pick up an actor, right?
Set a variable in the newly created instance, not in the one that’s being picked up and destroyed.

Thats correct. But what I have to do is to somehow run a function in widget class after I picked up the actor. This is why I made a bool to change its state after I picked up the actor.

How can I run a function when the pickup happens?

You need some kind of communication between classes. You can do it through the character or the controller, depending which class creates the widget.
For instance, when you pick up the actor, call a custom function in the widget with the actor class as an argument.

1 Like

Got it, now Im trying to do a character Cast in the widget and access its variables.

For instance, when you pick up the actor, call a custom function in the widget with the actor class as an argument.

Thats what im trying to do, I cant call a function if the widget doesnt know I picked it up, im using the NativeTick to check if the variable changes.

Okay, looks like I have fixed it thanks to you :relieved:, here is what I did:

Widget.cpp:

void UCPP_InventoryBar::NativeConstruct(){
    Super::NativeConstruct();

    InteractBase = NewObject<ACPP_InteractBase>(this, ACPP_InteractBase::StaticClass());
    LynchCharacter = Cast<ACH_LynchCharacter>(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0));
    AddInventoryBarSlots();
}

void UCPP_InventoryBar::NativeOnInitialized(){
}

void UCPP_InventoryBar::NativeTick(const FGeometry& MyGeometry, float DeltaTime){
    Super::NativeTick(MyGeometry, DeltaTime);

    
	if(InteractBase && LynchCharacter){
		if(LynchCharacter->bItemPickedUp){
            GEngine->AddOnScreenDebugMessage(-1,5.f,FColor::Orange,FString::Printf(TEXT("InteractBase->bItemPickedUp")));
            //UpdateInventoryBarSlot();
		}
	}
}

Added 1 line in the Widget.h:

	ACH_LynchCharacter* LynchCharacter;

In the Actor.cpp

void ACPP_InteractBase::Pickup(){
    GEngine->AddOnScreenDebugMessage(-1,5.f,FColor::Orange,FString::Printf(TEXT("+ %s"),(*ItemInfo.Name.ToString())));
	LynchCharacter->bItemPickedUp = true;
	Destroy();
}

In the character .h I just added a new variable:

	UPROPERTY()
	bool bItemPickedUp = false;

Now it works, and now I know that probably the gamemode, controller, character and maybe a few more classes run always at runtime, so they get updated, later I will reorganize stuff and put them into functions to make it run cleaner and look cleaner!

Thanks again!