handle menu UI interaction with FReply and blueprint

I created a menu following this tutorial. But I’m not able to react to the implemented click events via blueprint.

MainMenuHUD.h

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
 
#pragma once
 
#include "GameFramework/HUD.h"
#include "MainMenuHUD.generated.h"
 
// Provides an implementation of the game's Main Menu HUD, which will embed and respond
// to events triggered within SMainMenuUI.
UCLASS()
class MYGAME_API AMainMenuHUD : public AHUD
{
	GENERATED_UCLASS_BODY()

public:
	// Initializes the Slate UI and adds it as widget content to the game viewport.
	virtual void PostInitializeComponents() override;
 
    // Called by SMainMenu whenever the Play Game! button has been clicked.
	UFUNCTION(BlueprintImplementableEvent, Category = "Menus|Main Menu")
	void PlayGameClicked();
 
    // Called by SMainMenu whenever the Quit Game button has been clicked.
	UFUNCTION(BlueprintImplementableEvent, Category = "Menus|Main Menu")
	void QuitGameClicked();

private:
    // Reference to the Main Menu Slate UI.
	TSharedPtr<class SMainMenuUI> MainMenuUI;
};

MainMenuUI.h

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
 
#pragma once
 
#include "SlateBasics.h"
 
// Provides an implementation of the Slate UI representing the main menu.
class MYGAME_API SMainMenuUI : public SCompoundWidget
{
 
public:
	SLATE_BEGIN_ARGS(SMainMenuUI)
	{}
	SLATE_ARGUMENT(TWeakObjectPtr<class AMainMenuHUD>, MainMenuHUD)
	SLATE_END_ARGS()
 
    // Constructs and lays out the Main Menu UI Widget.
    // args Arguments structure that contains widget-specific setup information.
	void Construct(const FArguments& args);
 
	// Click handler for the Play Game! button – Calls MenuHUD’s PlayGameClicked() event.
	FReply PlayGameClicked();
 
	// Click handler for the Quit Game button – Calls MenuHUD’s QuitGameClicked() event.
	FReply QuitGameClicked();
 
    // Stores a weak reference to the HUD controlling this class.
	TWeakObjectPtr<class AMainMenuHUD> MainMenuHUD;

	// The used Style for the UI.
	const struct FGlobalStyle* MenuStyle;

	// FTexts for localization support
	FText PlayGame = NSLOCTEXT("MainMenu", "PlayGame", "Play Game!");
	FText QuitGame = NSLOCTEXT("MainMenu", "QuitGame", "Quit Game!");
	FText MainMenuTitle = NSLOCTEXT("MainMenu", "MainMenu", "Main Menu");
};

MainMenuUI.cpp

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
 
#include "MyGame.h"
#include "MainMenuUI.h"
#include "Engine.h"
#include "GlobalMenuStyle.h" 
#include "MenuStyles.h" 
 
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SMainMenuUI::Construct(const FArguments& args)
{
	MainMenuHUD = args._MainMenuHUD;
	MenuStyle = &FMenuStyles::Get().GetWidgetStyle<FGlobalStyle>("MainMenuStyle");
 
	ChildSlot
		[
			SNew(SOverlay)
			+ SOverlay::Slot()
			.HAlign(HAlign_Center)
			.VAlign(VAlign_Top)
			[
				SNew(STextBlock)
				.TextStyle(&MenuStyle->MenuTitleStyle)
				.Text(MainMenuTitle)
			]
			+ SOverlay::Slot()
			.HAlign(HAlign_Right)
			.VAlign(VAlign_Bottom)
			[
				SNew(SVerticalBox)
				+ SVerticalBox::Slot()
				[
					SNew(SButton)
					.ButtonStyle(&MenuStyle->MenuButtonStyle)
					.TextStyle(&MenuStyle->MenuButtonTextStyle)
					.Text(PlayGame)
					.OnClicked(this, &SMainMenuUI::PlayGameClicked)
				]
				+ SVerticalBox::Slot()
				[
					SNew(SButton)
					.ButtonStyle(&MenuStyle->MenuButtonStyle)
					.TextStyle(&MenuStyle->MenuButtonTextStyle)
					.Text(QuitGame)
					.OnClicked(this, &SMainMenuUI::QuitGameClicked)
				]
			]
		];
 
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
 
FReply SMainMenuUI::PlayGameClicked()
{
	if (GEngine)
	{
		GEngine->AddOnScreenDebugMessage(-1, 3.f, FColor::Yellow, TEXT("PlayGameClicked"));
	}
 
	return FReply:Handled();
}
 
FReply SMainMenuUI::QuitGameClicked()
{
	if (GEngine)
	{
		GEngine->AddOnScreenDebugMessage(-1, 3.f, FColor::Yellow, TEXT("QuitGameClicked"));
	}

	return FReply::Unhandled();
}

I used FReply::Handled() and FReply::Unhandled() but both don’t seem to work.

As far as I understand the both button click events of the UI refer to the methods of the HUD which are BlueprintImplementableEvents. If I created a blueprint based on the MainMenuHUD class I’m able to implement a behavior for the events but they seem never to be triggered. The blueprint HUD and the C++ UI are set to the current map.

How do I implement the behavior of the button click events via blueprint correctly or is there a mistake in code?

cmartel answered this in the forums:

If your prints are being called, then the function is being called and the reply won’t change anything.

What a handled reply does is prevent the event from bubbling up to parent widgets. So, say you had a button containing another button, if the inner button replies Unhandled to MouseDown, the event will bubble up to the outer button and give it a chance to handle MouseDown as well. Normally, you’ll want to return Handled when you do something with the event. (There are exceptions to this rule, but this is not one of those cases.)

If you’re just following the tutorial as-is, then the SMainMenuUI::PlayGameClicked()/SMainMenuUI::QuitGameClicked() handlers are not actually calling the events on MainMenuHUD. Add a MainMenuHUD->PlayGameClicked() and MainMenuHUD->QuitGameClicked() respectively in each handler, that should fill the missing link to calling your blueprint events.

-Camille