How to set the widget class to none in c++

I’ve been trying for hours and still can’t find any solution I’ve tried NULL, nullptr and it just ends up crashing. Any solution? Also could you provide help on setting the widget class cause the current solution doesn’t crash but nothing shows up when I set it. Thanks in advance.

Where are you trying to clear it?

  • Inside of a widget
  • Inside of a widgetComponent

You could try checking the RemoveWidgetFromScreen() function
if you want to remove a widget then you can call RemoveFromParent(); directly on it.
it all depends on the expanded use case that you need.

This is from the widgetComponent

void UWidgetComponent::SetWidgetClass(TSubclassOf<UUserWidget> InWidgetClass)
{
	if (WidgetClass != InWidgetClass)
	{
		WidgetClass = InWidgetClass;

		if (FSlateApplication::IsInitialized())
		{
			if (HasBegunPlay() && !GetWorld()->bIsTearingDown)
			{
				if (WidgetClass)
				{
					UUserWidget* NewWidget = CreateWidget(GetWorld(), WidgetClass);
					SetWidget(NewWidget);
				}
				else
				{
					SetWidget(nullptr);
				}
			}
		}
	}
}

And in SetWidget

void UWidgetComponent::SetWidget(UUserWidget* InWidget)
{
	if (InWidget != nullptr)
	{
		SetSlateWidget(nullptr);
	}

	if (Widget)
	{
		RemoveWidgetFromScreen();
	}

	Widget = InWidget;

	UpdateWidget();
}

I put a widget component on a pawn and set the widget class of the component to a widget BP in c++ but don’t know how to set it to none using another function. Tysm for the reply tho!

WidgetC.zip (44.4 KB)
1 key turns the widget component on and off via c++

The crucial part:


void AMyCharacter::SetWidget(TSubclassOf<class UUserWidget> passedWidget) {
	
	if (passedWidget != nullptr) {
		UUserWidget* widget = CreateWidget<UUserWidget>(GetWorld(), passedWidget);
		widgetComponent->SetWidget(widget);
	} else {
		widgetComponent->SetWidget(nullptr);
	}
	
}

``

Sry for the late reply I was busy all day. I forgot to mention that the function setting the widget is in the pawn class and gets called in the character class under certain conditions but I debugged it previously and what’s crashing it is setting it to NULL or nullptr and idk why.
Here’s the function:

void ATargetDummy::EnableWidget()
{
	if (LockedOnWidget->GetWidgetClass() != nullptr)
	{
		LockedOnWidget->SetWidgetClass(nullptr);
	}
	else
	{
		LockedOnWidget->SetWidgetClass(WidgetBPContainer);
	}
}

Btw WidgetBPContainer is a TSubclassOf and it doesn’t crash when I set it in the function but idk no widget displays when it’s set.

You can’t use SetWidetClass. You have to do it more manually like the code I showed you above.
Your code crashes because SetWidetClass internally spawns a widget from the passsed class and then sets it. If its passed nullptr then it crashes on the spawn process.

Do it manually like I showed you and it will run ok.

But the one above sets the widget component of the character and I don’t have a widget component on the character.

What is LockedOnWidget? is it a referene to a UUserwiget then?
If so just call removefromparent on it and set the uproperty to nullptr.

Just add in checks to where you access the variable.

It’s the UWidgetComponent. I’m trying to set a widget BP for the widget class of the widget component.

This code sets the widget class FOR the widget component.

If you are setting a pure BP widget without a c++ base class then maybe call a blueprint implemented function from within c++ for it to set it there? Otherwise keep it pure c++

Crashed on setting to nullptr again.

Is your UWidgetComponent instantiated correctly in the CDO?
Perhaps it is the null pointer?

do you have something like this in your constructor?

LockedOnWidget= CreateDefaultSubobject<UWidgetComponent>(TEXT("Locked on widget"));
	LockedOnWidget->SetupAttachment(GetRootComponent());

Yes.

WidgetC2.zip (372.9 KB)

Here is a working example. Toggle with space bar. All c++ only thing you need to set is the widget from the editor.

Implemented so that it mirrors your functions.

You have both enable and disable to see it in action. Calling enable if the blueprint widget is set to none will clear it from the screen and set it to none in the widget component.

Here is the main code

.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "MyCharacter.generated.h"

UCLASS()
class YOUR_API AMyCharacter : public ACharacter
{
	GENERATED_BODY()

public:
	AMyCharacter();

protected:
	virtual void BeginPlay() override;

public:	
	virtual void Tick(float DeltaTime) override;

	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

	UPROPERTY(EditAnywhere,BlueprintReadWrite)
	class UWidgetComponent* LockedOnWidget;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TSubclassOf<class UUserWidget> WidgetBPContainer;

	UFUNCTION()
		void EnableWidget();
	
	UFUNCTION()
		void DisableWidget();

	void Toggle();

	bool bToggle = true;

	UPROPERTY();
	UUserWidget* widgetInstance;
};

.cpp

#include "MyCharacter.h"
#include "Components/WidgetComponent.h"


AMyCharacter::AMyCharacter()
{

	PrimaryActorTick.bCanEverTick = true;
	LockedOnWidget = CreateDefaultSubobject<UWidgetComponent>(TEXT("LockedOnWidget"));
	LockedOnWidget->SetupAttachment(GetRootComponent());
	LockedOnWidget->SetWidgetSpace(EWidgetSpace::Screen);
}


void AMyCharacter::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void AMyCharacter::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}


void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	check(PlayerInputComponent);
	PlayerInputComponent->BindAction("Toggle", IE_Pressed, this, &AMyCharacter::Toggle);
}

void AMyCharacter::EnableWidget() {	
	if (WidgetBPContainer != nullptr) {
		widgetInstance = CreateWidget<UUserWidget>(GetWorld(), WidgetBPContainer);
		LockedOnWidget->SetWidget(widgetInstance);
	} else {
		LockedOnWidget->SetWidget(nullptr);
		if (widgetInstance != nullptr) {
			widgetInstance->RemoveFromParent();
		}
	}	
}

void AMyCharacter::DisableWidget() {	
	LockedOnWidget->SetWidget(nullptr);
	if (widgetInstance != nullptr) {
		widgetInstance->RemoveFromParent();
	}	
}

void AMyCharacter::Toggle() {
 	if (bToggle == true) {
		EnableWidget();		
	}
	else {
		DisableWidget();		
	}
	bToggle = !bToggle;
}

Spacebar toggles the widget through key binds

What’s the difference between SetWidget and SetWidgetClass?

  • SetWidet sets the the already spawned widget class instanced object for the WidgetComponent
  • SetWidetClass calls a spawn function on the passed uclass and then calls SetWidet on the WidgetComponent.

SetWidetClass fails if you pass in a nullptr, because you cannot spawn a widget from nullptr, causing a crash.

I managed to solve it the problem was in the character class I was calling the enable widget function when the pawn I was casting to was set to nullptr.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.