Download

UUserWidget* CurrentWidget not set, yet still returns true.

Heya, so I’m trying to figure out C++ in Unreal here and keep going back to the Match3 example to essentially do a copy/paste to get some similar functionality.

I’ve gotten stuck on this here, what is CurrentWidget doing in this case? The only mention of this widget us inside Match3GameMode, I can’t see it being set anywhere so in my game CurrentWidget will never be true, but I just can’t see how this is different from Match3, I’ve searched through all Match3 classes and the code snippets below are all I can find.

Is this an Unreal keyword and therefore not need to get set? In Match3 when it’s game over CurrentWidget will return True, somehow, so it does get set although the code for when it gets set is nowhere to be found.

Am a bit clueless here - am very new to C++ in Unreal too - hope that someone here would know more. Thanks.

Match3GameMode.h:


/** The widget instance that we are using as our menu. */
UPROPERTY()
UUserWidget* CurrentWidget;


Match3GameMode.cpp:




void AGenMobileGameMode::GameOver()
{
     [snip for clarity]

	ChangeMenuWidget(bGameWillBeWon ? VictoryWidgetClass : DefeatWidgetClass);
}


void AMatch3GameMode::ChangeMenuWidget(TSubclassOf<UUserWidget> NewWidgetClass)
{
	if (CurrentWidget)
	{
		CurrentWidget->RemoveFromViewport();
		CurrentWidget = nullptr;
	}
	if (NewWidgetClass)
	{
		if (AMatch3PlayerController* PC = Cast<AMatch3PlayerController>(UMatch3BlueprintFunctionLibrary::GetLocalPlayerController(this)))
		{
			CurrentWidget = CreateWidget<UUserWidget>(PC, NewWidgetClass);
			if (CurrentWidget)
			{
				CurrentWidget->AddToViewport();
			}
		}
	}
}

Declare it on your header file as this:


/** The widget instance that we are using as our menu. */
UPROPERTY(Transient)
UUserWidget* CurrentWidget;

And on the cpp file, add to the constructor:



CurrentWidget = nullptr;


this might solve most of your problems :slight_smile:

Now for the explanation: When you allocate a space in memory, the computer does not “clean” what’s there before, you need to do that yourself. In this case, that’s done in the constructor :slight_smile:

Thanks, that’s good to know. It doesn’t seem to do much though, and keep in mind, this is code I’m grabbing from the Match3 project and I haven’t changed this part. There’s obviously something I’m missing though.

I added the call to function as well in my first post, it might help…? This line is what calls the popup of the Victory and Defeat windows, although nothing happens in my case:


ChangeMenuWidget(bGameWillBeWon ? VictoryWidgetClass : DefeatWidgetClass);

There are UI widgets called VictoryWidget and DefeatWidget, are those what these classes *automatically *refer to somehow, or do I need to do something else? In the case of Match3 there is a UI widget created in the editor with the name VictoryScreen and in this line it’s what will display if bGameWillBeWon = True. Now the only reference to setting VictoryWidgetClass is similar to my other question about CurrentWidget:

In the header:


/** The widget class we will use as our game over screen when the player wins. */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Game")
	TSubclassOf<UUserWidget> VictoryWidgetClass;

I can’t see any mention of VictoryWidgetClass. The VictoryScreen UMG in the editor has no mention of being of ‘VictoryWidgetClass’ either, the parent class is ‘User Widget’ as per normal as well.

I just can’t seem to see a connection between VictoryWidgetClass in C++ and VictoryScreen in the editor…

Thanks for the help!

Ok I am going to let my reply just live there to show the world my stupidity. I missed setting the VictoryScreen to a default value in the class so it was set to ‘none’.

My original question still applies, I’m not sure what the purpose of declaring this is:


	/** The widget instance that we are using as our menu. */
	UPROPERTY(Transient)
	UUserWidget* CurrentWidget;

Maybe it will become clear further down the road… things seem to work now though.

Oh, I think I know what transient means here, but what benefit do I get from declaring it as a class whose objects should never be saved to disk?

Sorry I couldn’t reply earlier :slight_smile:

Apparently you managed to solve your issue! That’s great!

About transient… It’s a good practice. Do you want it saved, if for some reason, it needs to be saved? It’s along those lines :slight_smile:
The property will be excluded from any serializing operation that needs to be called, if I recall correctly.