メインコンテンツまでスキップ

Add custom matchmaking menu - Game client integration - (Unreal Engine module)

Last updated on March 12, 2025

What's on the menu

This tutorial shows you how to prepare the menu you will use to perform matchmaking using the sample matchmaking backend service. The menu is available in the Resources section and consist of the following files:

  • CustomMatchmakingWidget_Starter: A C++ class where most of the implementation will be.
    • Header file: /Source/AccelByteWars/TutorialModules/Play/CustomMatchmaking/UI/CustomMatchmakingWidget_Starter.h
    • CPP file: /Source/AccelByteWars/TutorialModules/Play/CustomMatchmaking/UI/CustomMatchmakingWidget_Starter.cpp
  • W_CustomMatchmaking_Starter: A Widget Blueprint class that was created and designed using Unreal Motion Graphics (UMG).
    • Widget Blueprint file: /Content/TutorialModules/Play/CustomMatchmaking/UI/W_CustomMatchmaking_Starter.uasset

We have provided a few things for you in the Header and CPP file.

  • A reference to a subsystem object in the Header file that you will later implement, along with the code to retrieve it on the CPP file.
private:
UPROPERTY()
UCustomMatchmakingSubsystem_Starter* Subsystem;
void UCustomMatchmakingWidget_Starter::NativeOnActivated()
{
// ...
Subsystem = GetGameInstance()->GetSubsystem<UCustomMatchmakingSubsystem_Starter>();
if (!Subsystem)
{
UE_LOG_CUSTOMMATCHMAKING(Fatal, TEXT("Can't retrieve UCustomMatchmakingSubsystem"))
}
// ...
}
  • This menu has differents states to show the relevant user interface based on the matchmaking state, which made possible by our AccelByteWars Widget Switcher, a custom Widget Switcher with predefined states.
    • Default: showing the Start Matchmaking button.
    • Loading: showing a loading indication, a message, and a cancel button.
    • Error: showing a retry and back button.
private:
// ...
UPROPERTY(BlueprintReadOnly, meta = (BindWidget, BlueprintProtected = true, AllowPrivateAccess = true))
UAccelByteWarsWidgetSwitcher* W_Root;
  • A function switch between states.
void UCustomMatchmakingWidget_Starter::SwitchWidget(const EAccelByteWarsWidgetSwitcherState State)
{
UWidget* FocusTarget = W_Root;
bool bIsBackable = true;

switch (State)
{
case EAccelByteWarsWidgetSwitcherState::Loading:
bIsBackable = false;
break;
case EAccelByteWarsWidgetSwitcherState::Not_Empty:
FocusTarget = Btn_StartMatchmaking;
break;
}

W_Root->SetWidgetState(State);

FocusTarget->SetUserFocus(GetOwningPlayer());

bIsBackHandler = bIsBackable;
Btn_Back->SetVisibility(bIsBackable ? ESlateVisibility::Visible : ESlateVisibility::Collapsed);

W_Root->ForceRefresh();
}

Default state

This is where player tells the game to connect to the sample matchmaking backend service and start the matchmaking process. This menu have two buttons, Start Matchmaking and Back button.

Preview of default state

Those buttons are declared in the Header file:

private:
// ...
UPROPERTY(BlueprintReadOnly, meta = (BindWidget, BlueprintProtected = true, AllowPrivateAccess = true))
UCommonButtonBase* Btn_StartMatchmaking;

UPROPERTY(BlueprintReadOnly, meta = (BindWidget, BlueprintProtected = true, AllowPrivateAccess = true))
UCommonButtonBase* Btn_Back;

As you might have guessed, the Back button is a way for player to go back to previous menu. We have already provided that functionality in the CPP file, by binding the built-in DeactivateWidget function on the button's OnClick.

void UCustomMatchmakingWidget_Starter::NativeOnActivated()
{
// ...
Btn_Back->OnClicked().AddUObject(this, &ThisClass::DeactivateWidget);
// ...
}

Loading state

As mentioned in the beginning, this state is achieved with our custom Widget Switcher. It consists of a loading message and a Cancel button. The loading message can be set by setting the value of W_Root->LoadingMessage. The OnClick event of the Cancel button can be set by manipulating W_Root->OnCancelClicked delegate. It can also be disabled / enabled, by setting the value of W_Root->bEnableCancelButton.

Preview of loading state

You might notice that, in the editor, there's a Back button in this state. The game will hide this Back button when switching to this state. You can see this logic in the SwitchWidget function that is mentioned in the previous section.

Error state

This state is also provided by our custom Widget Switcher. It consists of an error message, a Retry button, and the same Back button as the one in the Default state. The error message can be set by setting the value of W_Root->ErrorMessage. The OnClick event of the Retry button can be set by manipulating W_Root->OnRetryClicked delegate.

Preview of error state

Ready the UI

  1. Open the CustomMatchmakingWidget_Starter Header file and add the following function declarations. These are the functions that will be called when player presses certain button.
protected:
UFUNCTION()
void StartMatchmaking();

UFUNCTION()
void StopMatchmaking();
  1. Open the CustomMatchmakingWidget_Starter CPP file and define the StartMatchmaking function. Later, you will use this function to trigger the matchmaking process, but for now, add the dummy implementation below. We want the user to know that the game is currently attempting to start the matchmaking process, hence we change the widget's state to Loading with relevant message as soon as the function was triggered.
void UCustomMatchmakingWidget_Starter::StartMatchmaking()
{
W_Root->LoadingMessage = FText::FromString(TEXT_LOADING_REQUEST);
W_Root->bEnableCancelButton = false;
SwitchWidget(EAccelByteWarsWidgetSwitcherState::Loading);
// ...
}
  1. Define the StopMatchmaking function. You will call the actual stop matchmaking functionality here. For now, add the following dummy implementation. Just like before, we want to let the player know that the game is currently processing their request by changing the widget's state to Loading and relevant message at the start of the function.
void UCustomMatchmakingWidget_Starter::StopMatchmaking()
{
W_Root->LoadingMessage = FText::FromString(TEXT_LOADING_CANCEL);
SwitchWidget(EAccelByteWarsWidgetSwitcherState::Loading);
// ...
}
  1. Go to the NativeOnActivated function and add these implementation to the end of the function. This is to bind our dummy implementation for the start and stop matchmaking to the corresponding button.
void UCustomMatchmakingWidget_Starter::NativeOnActivated()
{
// ...
Btn_StartMatchmaking->OnClicked().AddUObject(this, &ThisClass::StartMatchmaking);
W_Root->OnCancelClicked.AddUObject(this, &ThisClass::StopMatchmaking);
W_Root->OnRetryClicked.AddUObject(this, &ThisClass::StartMatchmaking);
// ...
}
  1. Go to the NativeOnDeactivated function and add these implementation to the end of the function. This will make sure a clean close when the menu is closed.
void UCustomMatchmakingWidget_Starter::NativeOnDeactivated()
{
// ...
Btn_StartMatchmaking->OnClicked().RemoveAll(this);
W_Root->OnCancelClicked.RemoveAll(this);
W_Root->OnRetryClicked.RemoveAll(this);
// ...
}
  1. Go back to CustomMatchmakingWidget_Starter Header file and declare more functions. These functions will the one responsible to react to changing event from the matchmaking service.
protected:
// ...
void OnMatchmakingStarted();
void OnMessageReceived(const FMatchmakerPayload& Payload);
void OnMatchmakingFailed(const FString& ErrorMessage);
  1. Open the CustomMatchmakingWidget_Starter CPP file and define the OnMatchmakingStarted function. This handles when the backend have confirmed that we have succesfully requested a matchmake and it is currently in progress. Here, it will change the menu state to Loading.
void UCustomMatchmakingWidget_Starter::OnMatchmakingStarted()
{
W_Root->LoadingMessage = FText::FromString(TEXT_LOADING_FINDING_MATCH);
W_Root->bEnableCancelButton = true;
SwitchWidget(EAccelByteWarsWidgetSwitcherState::Loading);
}
  1. Define the OnMessageReceived function which handles when the game received any message from the matchmaking server. In this case, the game will simply show the message as the loading message.
void UCustomMatchmakingWidget_Starter::OnMessageReceived(const FMatchmakerPayload& Payload)
{
W_Root->LoadingMessage = FText::FromString(Payload.Message);
SwitchWidget(EAccelByteWarsWidgetSwitcherState::Loading);
}
  1. Define the OnMatchmakingFailed function which handles when the game received error. This function will change the menu state to Error and display the error message.
void UCustomMatchmakingWidget_Starter::OnMatchmakingFailed(const FString& ErrorMessage)
{
W_Root->ErrorMessage = FText::FromString(ErrorMessage);
SwitchWidget(EAccelByteWarsWidgetSwitcherState::Error);
}
  1. Build your project and open it in the Unreal Engine Editor. In the Editor, go to /Content/TutorialModules/Play/CustomMatchmaking/. You will find a data asset called DA_CustomMatchmaking. Open it and enable the Is Starter Mode Active. Then, save the data asset. This will activate the widgets so you can navigate through them when you play the game.

    Activate starter mode

  2. Play the game in the Editor and you will be able to navigate to Custom Matchmaking > Start Matchmaking if the implementation was successful.

Resources