Crash with UUserWidget C++

Hi! I’ve been having a headache with a problem.
I’ve been doing this code:

void ANotes::BeginPlay()
{
	Super::BeginPlay();

	_playerController = UGameplayStatics::GetPlayerController(GetWorld(), 0);

	if (_noteWidgetClass && _playerController) {
		if ((_noteWidget = CreateWidget<UUserWidget>(_playerController, _noteWidgetClass)) != nullptr) {
			if (UTextBlock* noteTextBlock = Cast<UTextBlock>(_noteWidget->GetWidgetFromName("NoteText"))) {
				noteTextBlock->SetText(_noteText);
			}
		}
	}
}

void ANotes::OnAction()
{
	if (_noteWidget && _playerController && _owningInventory->_bInspecting) {
		if (!_noteWidget->IsInViewport()) {
			_bNoSwitchableItem = true;
			_playerController->SetInputMode(FInputModeGameAndUI());
			_noteWidget->AddToViewport();
			_playerController->SetIgnoreLookInput(true);
			_playerController->SetIgnoreMoveInput(true);
		} else {
			_bNoSwitchableItem = false;
			_noteWidget->RemoveFromParent();
			_playerController->SetInputMode(FInputModeGameOnly());
			_playerController->bShowMouseCursor = false;
			_playerController->SetIgnoreLookInput(false);
			_playerController->SetIgnoreMoveInput(false);
		}
	}
}

The problem is that sometimes it crashes me on this exact line always:

_noteWidget->AddToViewport();

And I thought that it could be a problem creating the _noteWidget that don’t succeed of something, but it doesn’t seem to be the problem because sometimes when I open the note it works perfect but then when time passes sometimes it crashes when I execute again the OnAction and sometimes not. I put breakpoints to take a look at the _noteWidget variable and it seems that when it shows correctly the name of the Widget it’s “WBP_Notes_C” but when it crashes is “None”. So that makes me think that the _noteWidget it’s destroying at some point but I doesn’t figure why.

If anyone can help me it would be really apreciated :heart_hands:

Hello, there are a few questions.
Did you check (set a breakpoint) on BeginPlay? Maybe some conditions become false.
And second, I suggest that _noteWidgetClass you select from the editor menu. It’s worth checking if the right widget is selected. Believe me, there have been many times when I tried to find a bug and then found out that I just didn’t select the right widget🙃

Try switching

if (_noteWidget && _playerController && _owningInventory->_bInspecting) {

}

to

if (_noteWidget!=null &&  !_noteWidget->IsPendingKill() && _playerController && _owningInventory->_bInspecting) {

}

if should help in situations where the widget is destroyed or marked to be garbage collected.

Could it be that your _noteWidget is being garbage collected mid game?

if ((_noteWidget = CreateWidget<UUserWidget>(_playerController, _noteWidgetClass)) != nullptr)

Non-Initialization Assignments should not be performed in scope initializers like this.
Move the CreateWidget call out of the if expression like so:

noteWidget = CreateWidget(...)
if (noteWidget) {
...
}

It’s created good, so I guess that it’s not a widget class problem. But thanks anyways :heart_hands:

Hi @3dRaven @JPritchard1010 ! I tried both of your suggestions but it didn’t work, it gives the same crash :frowning:
I add a screenshot of the crash and the file of the crash too:


Crash.log (219.3 KB)

In the crash it gives the callstack that in Sophia.cpp in the line 296 crashes but it doesn’t make sense (it’s a null checking and also the code that executes is the one of above, the _currentHandItem OnAction():

	if (_inventory->_currentHandItem) {
		if (IOnActionInterface* onActionItem = Cast<IOnActionInterface>(_inventory->_currentHandItem)) {
			onActionItem->OnAction();
		}
	}

	if (_inventory->_currentChangeCameraItem) {
		if (_inventory->_currentChangeCameraItem->GetClass()->ImplementsInterface(UActorBlendInterface::StaticClass())) {
			IActorBlendInterface* changeCameraItem = Cast<IActorBlendInterface>(_inventory->_currentChangeCameraItem);

			if (changeCameraItem->_cameraActorBlend) {
				if (IInteractiveInterface* cameraItem = Cast<IInteractiveInterface>(changeCameraItem))
					cameraItem->UseInteraction();

				if (ICameraBlendInterface* item = Cast<ICameraBlendInterface>(changeCameraItem->_cameraActorBlend))
					item->UseInteraction();
			}
		}
	}

Thanks btw for trying to help :heart_hands:

Try a separate test in debugging mode in vs:

comment out the internals of
void ANotes::OnAction()
and in their place try this:

if(_noteWidget == nullptr){
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("_noteWidget is null”)); 
}

if(_playerController== nullptr){
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("_playerController is null”)); 
}
if(_owningInventory== nullptr){
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("_owningInventory is null”)); 
}


Track down the cause of the problem.

I tried the code you gave me adding another message to debug if it was entering the OnAction and it enters perfectly fine and doesn’t debug anything. I played like 5 minutes non-stop (having in mind that it usually crash in the first minute) and it didn’t debug anything.

is _noteWidget, _playerController & _owningInventory marked as a UPROPERTY?

Otherwise with time they are getting garbage collected.

You may pass the first null pointer test only for them to be destroyed within that scope causing it to fail.

I feel retarded hahaha I FORGOT THE UPROPERTY() :sob: :sob: :sob: :sob:
Thanks a lot for the help and the patience :heart_hands:

1 Like

It happens to all of us every now and then. It’s usually a signal to take a break and relax your mind :wink:

Coming back to a project after a walk & some fresh air usually works well.

1 Like