Add custom matchmaking menu - Game client integration - (Unreal Engine module)
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
- Header file:
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
- Widget Blueprint file:
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.
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
.
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.
Ready the UI
- 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();
- Open the
CustomMatchmakingWidget_Starter
CPP file and define theStartMatchmaking
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);
// ...
}
- 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);
// ...
}
- 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);
// ...
}
- 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);
// ...
}
- 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);
- Open the
CustomMatchmakingWidget_Starter
CPP file and define theOnMatchmakingStarted
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);
}
- 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);
}
- 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);
}
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 calledDA_CustomMatchmaking
. Open it and enable theIs Starter Mode Active
. Then, save the data asset. This will activate the widgets so you can navigate through them when you play the game.Play the game in the Editor and you will be able to navigate to Custom Matchmaking > Start Matchmaking if the implementation was successful.
Resources
- The files used in this tutorial section are available in the Byte Wars Unreal GitHub repository.
- AccelByteWars/Source/AccelByteWars/TutorialModules/Play/CustomMatchmaking/UI/CustomMatchmakingWidget_Starter.h
- AccelByteWars/Source/AccelByteWars/TutorialModules/Play/CustomMatchmaking/UI/CustomMatchmakingWidget_Starter.cpp
- AccelByteWars/Content/TutorialModules/Play/CustomMatchmaking/UI/W_CustomMatchmaking_Starter.uasset
- AccelByteWars/Content/TutorialModules/Play/CustomMatchmaking/DA_CustomMatchmaking.uasset