マッチセッション作成 UI - 専用サーバーを使用した参加可能なセッション - (Unreal Engine モジュール)
注釈:本資料はAI技術を用いて翻訳されています。
ピアツーピア(P2P)と専用サーバー(DS)の両方のサーバーモードを同時にサポートするために、メニューウィジェットと、メニューウィジェット内に表示されるセッション作成機能に接続するウィジェットを分離します。これらのウィジェットは、Create Match Session ウィジェットと Create Match Session DS ウィジェットです。
このチュートリアルでは、Create Match Session DS ウィジェットを準備します。
Create Match Session メニューについて
Create Match Session メニューは、Byte Wars でセッション作成のゲームモードとサーバータイプを選択するために使用されるウィジェットです。これはリソースセクションで提供されており、2つの部分で構成されています:
CreateMatchSessionWidget: ほとんどの実装が行われる C++ クラス。- ヘッダーファイル:
\Source\AccelByteWars\TutorialModules\MatchSessionEssentials\UI\CreateMatchSessionWidget.h - CPP ファイル:
\Source\AccelByteWars\TutorialModules\MatchSessionEssentials\UI\CreateMatchSessionWidget.cpp
- ヘッダーファイル:
W_CreateMatchSession: Unreal Motion Graphics(UMG)を使用して作成および設計されたウィジェット Blueprint クラス。- ウィジェット Blueprint ファイル:
\Content\TutorialModules\MatchSessionEssentials\UI\W_CreateMatchSession.uasset
- ウィジェット Blueprint ファイル:
Create Match Session メニューには4つの状態があります:
- Select Game Mode:ゲームモードの選択を表示します。Elimination と Team Deathmatch があります。
- Select Network Type:ネットワークタイプの選択を表示します。このモジュールでは、Dedicated Server が表示されます。
- Loading:作成ステータスとキャンセルボタンを表示します。
- Error:リトライボタンと戻るボタンを表示します。
状態の変更は、Unreal Motion Graphics の Widget Switcher と AccelByteWars Widget Switcher の組み合わせを使用して可能です。AccelByteWars Widget Switcher は、empty、loading、error、success という事前定義された状態を持つカスタム Widget Switcher です。以下は、ヘッダーファイルで言及されているコンポーネントの宣言です。
private:
// ...
UPROPERTY(BlueprintReadOnly, meta = (BindWidget, BlueprintProtected = true, AllowPrivateAccess = true))
UWidgetSwitcher* Ws_ContentOuter;
// ...
UPROPERTY(BlueprintReadOnly, meta = (BindWidget, BlueprintProtected = true, AllowPrivateAccess = true))
UAccelByteWarsWidgetSwitcher* Ws_Processing;
状態を切り替えるために、Create Match Session ウィジェットには次の関数があります:
void UCreateMatchSessionWidget::SwitchContent(const EContentType ContentType)
{
UWidget* Target = nullptr;
UWidget* FocusTarget = Btn_GameModeType_BackToCreateSession;
EAccelByteWarsWidgetSwitcherState ProcessingWidgetState = EAccelByteWarsWidgetSwitcherState::Empty;
bool bShowBackButton = true;
switch (ContentType)
{
case EContentType::SELECT_GAMEMODE:
Target = W_SelectGameModeType;
CameraTargetY = 600.0f;
ProcessingWidgetState = EAccelByteWarsWidgetSwitcherState::Loading;
FocusTarget = Btn_Elimination;
break;
case EContentType::SELECT_NETWORKTYPE:
Target = W_SelectGameModeNetworkType;
CameraTargetY = 750.0f;
ProcessingWidgetState = EAccelByteWarsWidgetSwitcherState::Loading;
FocusTarget = W_SelectGameModeNetworkTypeButtonOuter->HasAnyChildren() ?
W_SelectGameModeNetworkTypeButtonOuter->GetChildAt(0) :
Btn_ServerType_BackToCreateSession;
break;
case EContentType::LOADING:
Target = W_Processing;
CameraTargetY = 825.0f;
ProcessingWidgetState = EAccelByteWarsWidgetSwitcherState::Loading;
FocusTarget = Ws_Processing;
bShowBackButton = false;
break;
case EContentType::ERROR:
Target = W_Processing;
ProcessingWidgetState = EAccelByteWarsWidgetSwitcherState::Error;
CameraTargetY = 825.0f;
FocusTarget = Ws_Processing;
bShowBackButton = false;
break;
}
// Display the target widget. If the last widget is different, enable force state to directly display the correct initial state.
const bool bForceState = Ws_ContentOuter->GetActiveWidget() != Target;
Ws_ContentOuter->SetActiveWidget(Target);
Ws_Processing->SetWidgetState(ProcessingWidgetState, bForceState);
// Refresh widget focus.
Btn_GameModeType_BackToCreateSession->SetVisibility(bShowBackButton ? ESlateVisibility::Visible : ESlateVisibility::Collapsed);
DesiredFocusTargetButton = FocusTarget;
FocusTarget->SetUserFocus(GetOwningPlayer());
RequestRefreshFocus();
}
Select Game Mode 状態
ここでは、プレイヤーは提供されているゲームモードの1つ、Elimination または Team Deathmatch を選択するための2つのボタンを表示します。ボタンをクリックすると、ウィジェットはプレイヤーが選択したゲームモードを保存します。

これらのボタンはヘッダーファイルで宣言されています:
private:
// ...
UPROPERTY(BlueprintReadOnly, meta = (BindWidget, BlueprintProtected = true, AllowPrivateAccess = true))
UCommonButtonBase* Btn_Elimination;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget, BlueprintProtected = true, AllowPrivateAccess = true))
UCommonButtonBase* Btn_TeamDeathMatch;
保存された選択されたゲームモードは、この関数を介してアクセスできます:
public:
// ...
EGameModeType GetSelectedGameModeType() const { return SelectedGameModeType; }
EGameStyle GetSelectedGameStyle() const { return SelectedGameStyle; }
Select Network Type 状態
この状態では、プレイヤーはセッションが使用するネットワークタイプを選択できます。デフォルトでは、この状態は空です。ここに Create Match Session DS ウィジェットをアタッチします。

Loading 状態
この状態は、任意のメッセージに設定できるローディングメッセージと、有効化および無効化できるキャンセルボタンで構成されています。これを行うには、SwitchContent(EContentType::LOADING) を呼び出す直前に SetLoadingMessage を呼び出します:
void UCreateMatchSessionWidget::SetLoadingMessage(const FText& Message, const bool bEnableCancelButton) const
{
Ws_Processing->LoadingMessage = Message;
Ws_Processing->bEnableCancelButton = bEnableCancelButton;
}

Error 状態
この状態は、任意のメッセージに設定できるエラーメッセージと、有効化および無効化できるリトライボタンで構成されています。これを行うには、SwitchContent(EContentType::Error) を呼び出す直前に SetErrorMessage を呼び出します:
void UCreateMatchSessionWidget::SetErrorMessage(const FText& Message, const bool bShowRetryButton) const
{
Ws_Processing->ErrorMessage = Message;
Ws_Processing->bShowRetryButtonOnError = bShowRetryButton;
}

Create Match Session DS について
Create Match Session DS ウィジェットは、Create Match Session メニュー内に生成される1つのボタンのみで構成されています。これはリソースセクションで利用可能で、2つの部分で構成されています:
CreateMatchSessionDSWidget_Starter: ほとんどの実装が行われる C++ クラス。- ヘッダーファイル:
\Source\AccelByteWars\TutorialModules\Play\MatchSessionDS\UI\CreateMatchSessionDSWidget_Starter.h - CPP ファイル:
\Source\AccelByteWars\TutorialModules\MatchSessionDS\UI\CreateMatchSessionDSWidget_Starter.cpp
- ヘッダーファイル:
W_CreateMatchSession: Unreal Motion Graphics(UMG)を使用して作成および設計されたウィジェット Blueprint クラス。- ウィジェット Blueprint ファイル:
\Content\TutorialModules\MatchSessionDS\UI\W_CreateMatchSession.uasset
- ウィジェット Blueprint ファイル:
ヘッダーファイルには、セッション機能へのゲートウェイである OnlineSession、ボタン自体、および親ウィジェットへのポインタがあります。
protected:
// ...
UPROPERTY()
UAccelByteWarsOnlineSessionBase* OnlineSession;
private:
UPROPERTY(BlueprintReadOnly, meta = (BindWidget, BlueprintProtected = true, AllowPrivateAccess = true))
UCommonButtonBase* Btn_StartMatchSessionDS;
UPROPERTY()
UCreateMatchSessionWidget* W_Parent;
Online Session クラスと親ウィジェットを割り当てるコードは、NativeOnActivated() 関数で確認できます。
void UCreateMatchSessionDSWidget_Starter::NativeOnActivated()
{
// ...
// Get online session
UOnlineSession* BaseOnlineSession = GetWorld()->GetGameInstance()->GetOnlineSession();
if (!ensure(BaseOnlineSession))
{
return;
}
OnlineSession = Cast<UAccelByteWarsOnlineSessionBase>(BaseOnlineSession);
// Get parent menu widget
W_Parent = GetFirstOccurenceOuter<UCreateMatchSessionWidget>();
if (!ensure(W_Parent))
{
return;
}
// ...
}
以下は、Create Match Session DS ウィジェットのプレビューです。
Create Match Session DS ウィジェットを準備する
Create Match Session DS ウィジェットに必要な機能は、Create Session と Cancel Joining Session です。これらの機能のためにウィジェットを準備します。
-
CreateMatchSessionDSWidget_Starterヘッダーファイルを開き、次の関数宣言を追加します:protected:
UFUNCTION()
void CreateSession() const;
void OnCreateSessionComplete(FName SessionName, bool bSucceeded) const; -
CreateMatchSessionDSWidget_StarterCPP ファイルを開き、以下の実装を追加します。CreateSessionでは、Create Match Session メニューウィジェットの状態を「Loading」状態に変更し、キャンセルボタンを無効にします。これは、リクエストの送信中にキャンセルできないためです。OnCreateSessionComplete()では、リクエストが成功した場合、メニューウィジェットの状態をキャンセルボタンが有効な Loading に変更します。そうでない場合は、メニューウィジェットの状態を Error に変更します。void UCreateMatchSessionDSWidget_Starter::CreateSession() const
{
if (OnlineSession->ValidateToStartSession.IsBound() &&
!OnlineSession->ValidateToStartSession.Execute())
{
return;
}
// ...
W_Parent->SetLoadingMessage(TEXT_REQUESTING_SESSION_CREATION, false);
W_Parent->SwitchContent(UCreateMatchSessionWidget::EContentType::LOADING);
// ...
}void UCreateMatchSessionDSWidget_Starter::OnCreateSessionComplete(FName SessionName, bool bSucceeded) const
{
// Abort if not a game session.
if (!SessionName.IsEqual(OnlineSession->GetPredefinedSessionNameFromType(EAccelByteV2SessionType::GameSession)))
{
return;
}
if (bSucceeded)
{
W_Parent->SetLoadingMessage(TEXT_JOINING_SESSION, true);
W_Parent->SwitchContent(UCreateMatchSessionWidget::EContentType::LOADING);
}
else
{
W_Parent->SetErrorMessage(TEXT_FAILED_TO_CREATE_SESSION, true);
W_Parent->SwitchContent(UCreateMatchSessionWidget::EContentType::ERROR);
}
} -
キャンセル参加機能のコードを記述します。
CreateMatchSessionDSWidget_Starterヘッダーファイルに戻り、次の関数宣言を追加します:protected:
// ...
UFUNCTION()
void CancelJoiningSession() const;
void OnCancelJoiningSessionComplete(FName SessionName, bool bSucceeded) const; -
CreateMatchSessionDSWidget_StarterCPP ファイルを開き、以下の関数実装を追加します。CancelJoiningSession()では、Create Match Session メニューウィジェットの状態をキャンセルボタンが無効な Loading に変更します。OnCancelJoiningSessionComplete()が成功した場合は、Select Game Mode 状態に戻ります。そうでない場合は、Error 状態に遷移します。void UCreateMatchSessionDSWidget_Starter::CancelJoiningSession() const
{
W_Parent->SetLoadingMessage(TEXT_LEAVING_SESSION, false);
W_Parent->SwitchContent(UCreateMatchSessionWidget::EContentType::LOADING);
// ...
}void UCreateMatchSessionDSWidget_Starter::OnCancelJoiningSessionComplete(FName SessionName, bool bSucceeded) const
{
// Abort if not a game session.
if (!SessionName.IsEqual(OnlineSession->GetPredefinedSessionNameFromType(EAccelByteV2SessionType::GameSession)))
{
return;
}
if (bSucceeded)
{
W_Parent->SwitchContent(UCreateMatchSessionWidget::EContentType::SELECT_GAMEMODE);
}
else
{
W_Parent->SetErrorMessage(TEXT_FAILED_TO_LEAVE_SESSION, false);
W_Parent->SwitchContent(UCreateMatchSessionWidget::EContentType::ERROR);
}
} -
専用サーバーの準備ができたとき、またはエラーが発生したときにプレイヤーに知らせることもできます。
CreateMatchSessionDSWidget_Starterヘッダーファイルに戻り、この関数宣言を追加します:protected:
// ...
void OnSessionServerUpdateReceived(
const FName SessionName,
const FOnlineError& Error,
const bool bHasClientTravelTriggered) const; -
CreateMatchSessionDSWidget_StarterCPP ファイルを開き、この関数実装を追加します。この関数が成功した場合は、ローディングメッセージを変更します。そうでない場合は、エラーを表示します。void UCreateMatchSessionDSWidget_Starter::OnSessionServerUpdateReceived(
const FName SessionName,
const FOnlineError& Error,
const bool bHasClientTravelTriggered) const
{
// Abort if not a game session.
if (!SessionName.IsEqual(OnlineSession->GetPredefinedSessionNameFromType(EAccelByteV2SessionType::GameSession)))
{
return;
}
if (Error.bSucceeded && !bHasClientTravelTriggered)
{
// Keep showing the loading state until the client travels to the server.
W_Parent->SetLoadingMessage(TEXT_JOINING_SESSION, true);
W_Parent->SwitchContent(UCreateMatchSessionWidget::EContentType::LOADING);
}
else if (!bHasClientTravelTriggered && !Error.bSucceeded)
{
W_Parent->SetErrorMessage(TEXT_FAILED_TO_JOIN_SESSION, false);
W_Parent->SwitchContent(UCreateMatchSessionWidget::EContentType::ERROR);
}
} -
すべての関数が宣言および実装されたので、ウィジェットコンポーネントをこれらの関数にバインドできます。
CreateMatchSessionDSWidget_StarterCPP ファイルで、NativeOnActivated()関数に移動し、次のコードを追加します:void UCreateMatchSessionDSWidget_Starter::NativeOnActivated()
{
// ...
Btn_StartMatchSessionDS->OnClicked().AddUObject(this, &ThisClass::CreateSession);
} -
バインディングが完了したら、ウィジェットが使用されなくなったときにバインドを解除するコードを実装します。CPP ファイルで、
NativeOnDeactivatedに移動し、次のコードを追加します:void UCreateMatchSessionDSWidget_Starter::NativeOnDeactivated()
{
// ...
Btn_StartMatchSessionDS->OnClicked().RemoveAll(this);
W_Parent->GetProcessingWidgetComponent()->OnRetryClicked.RemoveAll(this);
W_Parent->GetProcessingWidgetComponent()->OnCancelClicked.RemoveAll(this);
} -
プロジェクトをビルドし、完了したら Unreal Editor で開きます。
-
Unreal Editor で、Content Browser から
Content\TutorialModules\Play\MatchSessionDS\UI\に移動し、W_CreateMatchSessionDS_Starterを開きます。Bind Widgets タブですべてのウィジェットが適切にバインドされていること、および Parent class がCreateMatchSessionDSWidget_Starterに設定されていることを確認します。
-
Content\TutorialModules\Play\MatchSessionDS\DA_MatchSessionDSEssentials.uassetを開き、Is Starter Mode Activeを有効にします。Data Asset を保存します。
-
エディタで Play をクリックします。Online Play > Play Online > Create Match Session に移動します。正しく実装されていれば、UI が表示されます。
リソース
- このチュートリアルセクションで使用されているファイルは、Byte Wars GitHub リポジトリで入手できます。
- AccelByteWars/Content/TutorialModules/Play/MatchSessionDS/UI/W_CreateMatchSessionDS_Starter.uasset
- AccelByteWars/Source/AccelByteWars/TutorialModules/Play/MatchSessionDS/UI/CreateMatchSessionDSWidget_Starter.h
- AccelByteWars/Source/AccelByteWars/TutorialModules/Play/MatchSessionDS/UI/CreateMatchSessionDSWidget_Starter.cpp
- AccelByteWars/Content/TutorialModules/Play/MatchSessionDS/UI/DA_MatchSessionDSEssentials.uasset