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

マッチセッション作成 UI を追加する - ピアツーピアで参加可能なセッション - (Unreal Engine モジュール)

Last updated on February 4, 2026

注釈:本資料はAI技術を用いて翻訳されています。

両方のサーバーモード(ピアツーピア(P2P)と専用サーバー(DS))を同時にサポートするには、メニューウィジェットと、メニューウィジェット内に表示されるセッション作成機能に接続するウィジェットを分離します。これらのウィジェットは、Create Match Session ウィジェットと Create Match Session P2P ウィジェットです。

このチュートリアルでは、Create Match Session P2P ウィジェットを準備します。

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

Create Match Session メニューには4つの状態があります。

  • Select Game Mode: ゲームモードの選択肢、EliminationTeam Deathmatch を表示します。
  • Select Network Type: ネットワークタイプの選択肢を表示します。このモジュールでは、P2P が表示されます。
  • Loading: 作成ステータスとキャンセルボタンを表示します。
  • Error: リトライボタンと戻るボタンを表示します。

状態の変更は、Unreal Motion Graphics の Widget SwitcherAccelByteWars 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 状態

ここでは、プレイヤーは提供される2つのゲームモード、Elimination または Team Deathmatch のいずれかを選択するための2つのボタンを表示します。ボタンをクリックすると、ウィジェットはプレイヤーが選択したゲームモードを保存します。

Preview of the Select Game Mode state Unreal Byte Wars joinable sessions peer-to-peer

これらのボタンはヘッダーファイルで宣言されています。

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 P2P ウィジェットをアタッチする場所です。

Preview of the Select Network Type state Unreal Byte Wars joinable sessions peer-to-peer

Loading 状態

この状態は、任意のメッセージに設定できるテキストと、有効または無効にできるキャンセルボタンで構成されています。これを行うには、SwitchContent(EContentType::LOADING) を呼び出す直前に SetLoadingMessage を呼び出します。

void UCreateMatchSessionWidget::SetLoadingMessage(const FText& Message, const bool bEnableCancelButton) const
{
Ws_Processing->LoadingMessage = Message;
Ws_Processing->bEnableCancelButton = bEnableCancelButton;
}

Preview of the Loading state Unreal Byte Wars joinable sessions peer-to-peer

Error 状態

この状態は、任意のメッセージに設定できるテキストと、有効または無効にできるリトライボタンで構成されています。これを行うには、SwitchContent(EContentType::Error) を呼び出す直前に SetErrorMessage を呼び出します。

void UCreateMatchSessionWidget::SetErrorMessage(const FText& Message, const bool bShowRetryButton) const
{
Ws_Processing->ErrorMessage = Message;
Ws_Processing->bShowRetryButtonOnError = bShowRetryButton;
}

Preview of the Error state Unreal Byte Wars joinable sessions peer-to-peer

Create Match Session P2P について

Create Match Session P2P ウィジェットには、Create Match Session メニュー内に生成されるボタンがあります。リソースセクションで利用可能で、2つの部分で構成されています。

  • CreateMatchSessionP2PWidget_Starter: ほとんどの実装が行われる C++ クラス。
    • ヘッダーファイル: \Source\AccelByteWars\TutorialModules\Play\MatchSessionP2P\UI\CreateMatchSessionP2PWidget_Starter.h
    • CPP ファイル: \Source\AccelByteWars\TutorialModules\MatchSessionP2P\UI\CreateMatchSessionP2PWidget_Starter.cpp
  • W_CreateMatchSession: Unreal Motion Graphics(UMG)を使用して作成および設計されたウィジェット Blueprint クラス。
    • ウィジェット Blueprint ファイル: \Content\TutorialModules\MatchSessionP2P\UI\W_CreateMatchSession.uasset

ヘッダーファイルには、セッション機能へのゲートウェイである OnlineSession、ボタン自体、および親ウィジェットへのポインタが表示されます。

protected:
// ...
UPROPERTY()
UAccelByteWarsOnlineSessionBase* OnlineSession;
private:
UPROPERTY(BlueprintReadOnly, meta = (BindWidget, BlueprintProtected = true, AllowPrivateAccess = true))
UCommonButtonBase* Btn_StartMatchSessionP2P;

UPROPERTY()
UCreateMatchSessionWidget* W_Parent;

Online Session クラスと親ウィジェットを割り当てるコードは、NativeOnActivated() 関数にあります。

void UCreateMatchSessionP2PWidget_Starter::NativeOnActivated()
{
// ...
// Get online session
UOnlineSession* BaseOnlineSession = GetWorld()->GetGameInstance()->GetOnlineSession();
if (!ensure(BaseOnlineSession))
{
return;
}
OnlineSession = Cast<UAccelByteWarsOnlineSessionBase>(BaseOnlineSession);
ensure(OnlineSession);

// Get parent menu widget
W_Parent = GetFirstOccurenceOuter<UCreateMatchSessionWidget>();
if (!ensure(W_Parent))
{
return;
}
// ...
}

以下は、Create Match Session P2P ウィジェットのプレビューです。

Preview of the Create Match Session P2P widget Unreal Byte Wars joinable sessions peer-to-peer

Create Match Session P2P ウィジェットを準備する

Create Match Session P2P ウィジェットに必要な機能は、セッションの作成とセッション参加のキャンセルです。これらの機能のためにウィジェットを準備します。

  1. CreateMatchSessionP2PWidget_Starter ヘッダーファイルを開き、次の関数宣言を追加します。

    protected:
    UFUNCTION()
    void CreateSession() const;

    void OnCreateSessionComplete(FName SessionName, bool bSucceeded) const;
  2. CreateMatchSessionP2PWidget_Starter CPP ファイルを開き、以下の関数実装を追加します。CreateSession では、Create Match Session メニューウィジェットの状態を Loading 状態に変更し、キャンセルボタンを無効にします。これは、リクエストの送信中にキャンセルできないためです。OnCreateSessionComplete() では、リクエストが成功した場合、メニューウィジェットの状態をキャンセルボタンが有効な Loading に変更します。そうでない場合は、メニューウィジェットの状態を Error に変更します。

    void UCreateMatchSessionP2PWidget_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 UCreateMatchSessionP2PWidget_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);
    }
    }
  3. セッション参加のキャンセル機能のコードを追加します。CreateMatchSessionP2PWidget_Starter ヘッダーファイルに戻り、次の関数宣言を追加します。

    protected:
    // ...
    UFUNCTION()
    void CancelJoiningSession() const;

    void OnCancelJoiningSessionComplete(FName SessionName, bool bSucceeded) const;
  4. CreateMatchSessionP2PWidget_Starter CPP ファイルを開き、以下の関数実装を追加します。CancelJoiningSession() では、Create Match Session メニューウィジェットの状態をキャンセルボタンが無効な Loading に変更します。OnCancelJoiningSessionComplete() では、成功した場合、Select Game Mode 状態に戻ります。そうでない場合は、Error 状態に遷移します。

    void UCreateMatchSessionP2PWidget_Starter::CancelJoiningSession() const
    {
    W_Parent->SetLoadingMessage(TEXT_LEAVING_SESSION, false);
    W_Parent->SwitchContent(UCreateMatchSessionWidget::EContentType::LOADING);
    // ...
    }
    void UCreateMatchSessionP2PWidget_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);
    }
    }
  5. サーバーの準備が整ったとき、またはエラーが発生したときにプレイヤーに知らせます。P2P では、理想的には、OnJoinComplete が呼び出された直後にクライアントがサーバーに直接参加できるはずですが、これをセーフティネットとして実装しています。CreateMatchSessionP2PWidget_Starter ヘッダーファイルに戻り、この関数宣言を追加します。

    protected:
    // ...
    void OnSessionServerUpdateReceived(
    const FName SessionName,
    const FOnlineError& Error,
    const bool bHasClientTravelTriggered) const;
  6. CreateMatchSessionP2PWidget_Starter CPP ファイルを開き、以下の関数実装を追加します。この関数では、成功した場合は単にローディングメッセージを変更します。そうでない場合は、エラーを表示します。

    void UCreateMatchSessionP2PWidget_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 P2P host.
    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);
    }
    }
  7. すべての関数が宣言および実装されたので、ウィジェットコンポーネントをこれらの関数にバインドします。CreateMatchSessionP2PWidget_Starter CPP ファイルで、NativeOnActivated() 関数に移動し、次のコードを追加します。

    void UCreateMatchSessionP2PWidget_Starter::NativeOnActivated()
    {
    // ...
    Btn_StartMatchSessionP2P->OnClicked().AddUObject(this, &ThisClass::CreateSession);
    }
  8. バインディングが完了したら、ウィジェットが使用されなくなったときにバインドを解除するコードを実装します。CPP ファイルで、NativeOnDeactivated に移動し、次のコードを追加します。

    void UCreateMatchSessionP2PWidget_Starter::NativeOnDeactivated()
    {
    // ...
    Btn_StartMatchSessionP2P->OnClicked().RemoveAll(this);
    W_Parent->GetProcessingWidgetComponent()->OnRetryClicked.RemoveAll(this);
    W_Parent->GetProcessingWidgetComponent()->OnCancelClicked.RemoveAll(this);
    }
  9. プロジェクトをビルドし、Unreal Editor で開きます。

  10. Unreal Editor で、Content Browser から Content\TutorialModules\Play\MatchSessionP2P\UI\ に移動し、W_CreateMatchSessionP2P_Starter を開きます。Bind Widgets タブですべてのウィジェットが適切にバインドされていること、および Parent classCreateMatchSessionP2PWidget_Starter に設定されていることを確認します。

    Bind widgets tab Unreal Byte Wars joinable sessions peer-to-peer

  11. Content\TutorialModules\Play\MatchSessionP2P\DA_MatchSessionP2PEssentials.uasset を開き、Is Starter Mode Active を有効にします。Data Asset を保存します。

    Data Asset changes preview Unreal Byte Wars joinable sessions peer-to-peer

  12. エディターでゲームをプレイします。Online Play > Play Online > Create Match Session に移動します。正しく実装されている場合、スターター UI が表示されます。

リソース