Slate Button Click Crash

Hi, Im working off of the Strategy Game example. I want to create an overlay menu for the game and was duplicating slate pause button code from the strategy game. The newly created button works, but the pause button now crashes the engine when clicked. Any ideas why?

Hey -

Does the Crash occur immediately when the button is pressed? Can you post the callstack and log files from the crash? Can you also post the code for how the button is generated / used?

Cheers

Hi

+SOverlay::Slot() // pause menu background overlay
			.VAlign(VAlign_Fill)
			.HAlign(HAlign_Fill)
			[
				SNew(SBorder)
				.Visibility(this, &SStrategySlateHUDWidget::GetPauseMenuBgVisibility)
				.VAlign(VAlign_Fill)
				.HAlign(HAlign_Fill)
				.BorderImage(FCoreStyle::Get().GetBrush("BlackBrush"))
				.BorderBackgroundColor(this, &SStrategySlateHUDWidget::GetOverlayColor)
				[
					SNew(SOverlay)
					// Return to main
					+SOverlay::Slot()
					.VAlign(VAlign_Center)
					.HAlign(HAlign_Center)
					[
						SAssignNew(MenuBox, SVerticalBox)
						+SVerticalBox::Slot()
						[
							SAssignNew(PauseMenuButtons[ButtonIndex++], SStrategyButtonWidget)
							.OwnerHUD(OwnerHUD)
							.Visibility(EVisibility::Visible)
							.TextFont(FStrategyStyle::Get().GetFontStyle(TEXT("StrategyGame.MenuFont")))
							.TextVAlign(EVerticalAlignment::VAlign_Center)
							.TextMargin(FMargin(0))
							.ButtonText(NSLOCTEXT("SStrategySlateHUDWidget", "MainMenu", "Main Menu"))
							.OnClicked(this, &SStrategySlateHUDWidget::OnReturnToMainMenu)
						]
					]
					
				]
			]
			+SOverlay::Slot()
			.VAlign(VAlign_Bottom)
			.HAlign(HAlign_Right)
			.Padding(FMargin(0,0,20,20))
			[
				SAssignNew(PauseButton,SStrategyButtonWidget)
				.OwnerHUD(OwnerHUD)
				.Visibility(EVisibility::Visible)
				.OnClicked(this, &SStrategySlateHUDWidget::TogglePauseMenu)
				.ButtonText(FText::GetEmpty())
			]

//location button
+ SOverlay::Slot()
.VAlign(VAlign_Fill)
.HAlign(HAlign_Fill)
[
SNew(SBorder)
.Visibility(EVisibility::Visible)//this, &SStrategySlateHUDWidget::GetPauseMenuBgVisibility
.VAlign(VAlign_Fill)
.HAlign(HAlign_Fill)
.BorderImage(FCoreStyle::Get().GetBrush(“BlackBrush”))
.BorderBackgroundColor(this, &SStrategySlateHUDWidget::GetOverlayColor)
[
SNew(SOverlay)
// Return to main
+ SOverlay::Slot()
.VAlign(VAlign_Center)
.HAlign(HAlign_Center)
.Padding(FMargin(0, 0, 600, 300))
[
SAssignNew(LocationMenu, SVerticalBox)
+ SVerticalBox::Slot()
[
SAssignNew(LocationMenuButtons[LocationButtonInd++], SStrategyButtonWidget)
.OwnerHUD(OwnerHUD)
.Visibility(EVisibility::Visible)
.TextFont(FStrategyStyle::Get().GetFontStyle(TEXT(“StrategyGame.MenuFont”)))
.TextVAlign(EVerticalAlignment::VAlign_Center)
.TextMargin(FMargin(0))
.ButtonText(NSLOCTEXT(“SStrategySlateHUDWidget”, “Location”, “Pick Location”))
.OnClicked(this, &SStrategySlateHUDWidget::ToggleLocationMenu)
]
]
]
]

So the pause menu button works when i don’t have location button. When I insert the location button code in, when i click the pause menu button the engine crashes.

Sorry it’s messy

Can you post the callstack and logs from the crash as well? Do the pause button and location button share screen space (on the screen at the same time)? What happens when you click the location button? If pressing the location button crashes as well, can you try removing the code for the pause button and then testing the location button again?

link text

Location button works fine, but yes they share the same screen space.

So far I have been unable to reproduce the crash you mentioned. Could you post the project with the crash so that we can investigate it directly? If you’re able to upload the project to dropbox or google drive, you can instead send me an email on the forums with a link to download the project so that it remains private.

I sent you a private email with the download link to my google drive

Hey -

After looking at the project we found the following function inside the StrategyPlayerController class:

void AStrategyPlayerController::OnTapPressed(const FVector2D& ScreenPosition, float DownTime)
{
	FVector WorldPosition(0.f);
	AActor* const HitActor = GetFriendlyTarget(ScreenPosition, WorldPosition);
	
	SetSelectedActor(HitActor, WorldPosition);
	if (HitActor && HitActor->GetClass()->ImplementsInterface(UStrategyInputInterface::StaticClass()) )
	{
		IStrategyInputInterface::Execute_OnInputTap(HitActor);
	}
	else
	{
		if (HitActor->IsA(AMyStrategyActor::StaticClass()))
		{
			Cast<AMyStrategyActor>(HitActor)->onClicked();
			clickType = Cast<AMyStrategyActor>(HitActor)->getType();
			AMyGameState* MyGameState = GetWorld()->GetGameState<AMyGameState>();
			MyGameState->OnAction();
		}
	}
}

Here the if (HitActor->IsA...) can be triggered even if HitActor is null which is then dereferenced without being checked, and will crash. In this case the function should be written to check the conditions independent. The following rewrite of the class did not crash when tested:

void AStrategyPlayerController::OnTapPressed(const FVector2D& ScreenPosition, float DownTime)
{
	FVector WorldPosition(0.f);
	AActor* const HitActor = GetFriendlyTarget(ScreenPosition, WorldPosition);
	
	SetSelectedActor(HitActor, WorldPosition);
	if (HitActor)
	{
		if (HitActor->GetClass()->ImplementsInterface(UStrategyInputInterface::StaticClass()) )
		{
			IStrategyInputInterface::Execute_OnInputTap(HitActor);
		}
		else if (HitActor->IsA(AMyStrategyActor::StaticClass()))
		{
			Cast<AMyStrategyActor>(HitActor)->onClicked();
			clickType = Cast<AMyStrategyActor>(HitActor)->getType();
			AMyGameState* MyGameState = GetWorld()->GetGameState<AMyGameState>();
			MyGameState->OnAction();
		}
	}
}

Thanks so much