すべてを統合する - パーティでプレイする - (Unreal Engine モジュール)
注釈:本資料はAI技術を用いて翻訳されています。
UI をパーティでプレイするフローに接続する
PlayWithPartySubsystem_Starter サブシステムにパーティでプレイする実装を作成しました。このサブシステムには、パーティでのプレイに関連するイベントに基づいて通知とプロンプトを表示する関数がすでに用意されています。ただし、前述のように、ゲームセッションを開始するのは、それを開始したプレイヤーがパーティリーダーである場合のみ、かつ他のパーティメンバーが他のゲームセッションに参加していない場合のみにしたいと考えています。これを実現するには、検証を実行する関数が必要です。
-
PlayWithPartySubsystem_Starterクラスのヘッダーファイルを開き、以下の関数を宣言します。protected:
// ...
bool ValidateToStartPartyGameSession();
bool ValidateToJoinPartyGameSession(const FOnlineSessionSearchResult& SessionSearchResult);
bool ValidateToStartPartyMatchmaking(const EGameModeType GameModeType); -
まず
ValidateToStartPartyGameSession()関数を宣言します。PlayWithPartySubsystem_Starterクラスの CPP ファイルに、以下のコードを追加します。この関数は、ゲームセッションの開始者がパーティリーダーであるかどうかをチェックします。また、他のパーティメンバーが他のゲームセッションに参加しているかどうかもチェックします。bool UPlayWithPartySubsystem_Starter::ValidateToStartPartyGameSession()
{
// Abort if the interfaces are invalid.
if (!GetSessionInterface() || !GetOnlineSession())
{
UE_LOG_PLAYINGWITHPARTY(Warning, TEXT("Cannot validate to start party game session. Interfaces or online session are not valid."));
return false;
}
// If not in party session, no need to validate.
const FNamedOnlineSession* PartySession = GetSessionInterface()->GetNamedSession(
GetOnlineSession()->GetPredefinedSessionNameFromType(EAccelByteV2SessionType::PartySession));
if (!PartySession)
{
UE_LOG_PLAYINGWITHPARTY(Log, TEXT("No need to validate to start party game session. Player is not in a party."));
return true;
}
const TSharedPtr<FOnlineSessionInfoAccelByteV2> PartySessionInfo = StaticCastSharedPtr<FOnlineSessionInfoAccelByteV2>(PartySession->SessionInfo);
if (!PartySessionInfo)
{
UE_LOG_PLAYINGWITHPARTY(Log, TEXT("No need to validate to start party game session. Player is not in a party."));
return true;
}
// Get current player.
FUniqueNetIdPtr UserId = nullptr;
if (GetIdentityInterface())
{
UserId = GetIdentityInterface()->GetUniquePlayerId(0);
}
// Only party leader is able to start party game session.
if (!GetOnlineSession()->IsPartyLeader(UserId))
{
if (GetPromptSubystem())
{
GetPromptSubystem()->PushNotification(PARTY_GAME_SESSION_MEMBER_SAFEGUARD_MESSAGE, FString(""));
}
return false;
}
// Only able to start party game session if other party members are not in other game session.
bool bResult = !IsGameSessionDifferFromParty(UserId);
/* Show notification that unable to start any game session
* if other party members are in other game session.*/
if (!bResult && GetPromptSubystem())
{
GetPromptSubystem()->PushNotification(PARTY_GAME_SESSION_LEADER_SAFEGUARD_MESSAGE, FString(""));
}
return bResult;
} -
ValidateToJoinPartyGameSession()関数を宣言します。PlayWithPartySubsystem_Starterクラスの CPP ファイルに、以下のコードを追加します。この関数はValidateToStartSession()と同じ動作をします。また、参加しようとしているゲームセッションに十分なスペースがあるかどうかもチェックします。bool UPlayWithPartySubsystem_Starter::ValidateToJoinPartyGameSession(const FOnlineSessionSearchResult& SessionSearchResult)
{
if (!ValidateToStartPartyGameSession())
{
return false;
}
// Abort if the interfaces are invalid.
if (!GetSessionInterface() || !GetOnlineSession())
{
UE_LOG_PLAYINGWITHPARTY(Warning, TEXT("Cannot validate to join party game session. Interfaces or online session are not valid."));
return false;
}
// If not in party session, no need to validate.
const FNamedOnlineSession* PartySession = GetSessionInterface()->GetNamedSession(
GetOnlineSession()->GetPredefinedSessionNameFromType(EAccelByteV2SessionType::PartySession));
if (!PartySession)
{
UE_LOG_PLAYINGWITHPARTY(Log, TEXT("No need to validate to join party game session. Player is not in a party."));
return true;
}
const TSharedPtr<FOnlineSessionInfoAccelByteV2> PartySessionInfo = StaticCastSharedPtr<FOnlineSessionInfoAccelByteV2>(PartySession->SessionInfo);
if (!PartySessionInfo)
{
UE_LOG_PLAYINGWITHPARTY(Log, TEXT("No need to validate to join party game session. Player is not in a party."));
return true;
}
TSharedPtr<FOnlineSessionInfoAccelByteV2> SessionInfo = StaticCastSharedPtr<FOnlineSessionInfoAccelByteV2>(SessionSearchResult.Session.SessionInfo);
if (!SessionInfo)
{
UE_LOG_PLAYINGWITHPARTY(Warning, TEXT("Cannot validate to join party game session. Session is not valid."));
return false;
}
TSharedPtr<FAccelByteModelsV2BaseSession> SessionData = SessionInfo->GetBackendSessionData();
if (!SessionData)
{
UE_LOG_PLAYINGWITHPARTY(Warning, TEXT("Cannot validate to join session. Session data is not valid."));
return false;
}
// Check if session slots is sufficient to join with party
int32 ActiveMemberCount = SessionData->Members.FilterByPredicate([](FAccelByteModelsV2SessionUser Temp)
{
return Temp.StatusV2 == EAccelByteV2SessionMemberStatus::JOINED;
}).Num();
bool bResult =
(SessionSearchResult.Session.SessionSettings.NumPublicConnections - ActiveMemberCount) >=
GetOnlineSession()->GetPartyMembers().Num();
// Notify that no more slots to join the session.
if (!bResult && GetPromptSubystem())
{
GetPromptSubystem()->PushNotification(JOIN_PARTY_GAME_SESSION_SAFEGUARD_MESSAGE, FString(""));
}
return bResult;
} -
ValidateToStartPartyMatchmaking()関数を宣言します。PlayWithPartySubsystem_Starterクラスの CPP ファイルに、以下のコードを追加します。この関数もValidateToStartSession()と同じ動作をします。また、ゲームモードがパーティでのプレイをサポートしているかどうかもチェックします。この場合、Byte Wars は Elimination モードでのパーティマッチメイキングをサポートしていません。これは、1人のメンバーのみのチームが必要なためです。bool UPlayWithPartySubsystem_Starter::ValidateToStartPartyMatchmaking(const EGameModeType GameModeType)
{
if (!ValidateToStartPartyGameSession())
{
return false;
}
// Abort if the interfaces are invalid.
if (!GetSessionInterface() || !GetOnlineSession())
{
UE_LOG_PLAYINGWITHPARTY(Warning, TEXT("Cannot validate to start party matchmaking. Interfaces or online session are not valid."));
return false;
}
// If not in party session, no need to validate.
const FNamedOnlineSession* PartySession = GetSessionInterface()->GetNamedSession(
GetOnlineSession()->GetPredefinedSessionNameFromType(EAccelByteV2SessionType::PartySession));
if (!PartySession)
{
UE_LOG_PLAYINGWITHPARTY(Log, TEXT("No need to validate to start party matchmaking. Player is not in a party."));
return true;
}
const TSharedPtr<FOnlineSessionInfoAccelByteV2> PartySessionInfo = StaticCastSharedPtr<FOnlineSessionInfoAccelByteV2>(PartySession->SessionInfo);
if (!PartySessionInfo)
{
UE_LOG_PLAYINGWITHPARTY(Log, TEXT("No need to validate to start party matchmaking. Player is not in a party."));
return true;
}
// Check whether matchmaking with party is supported using the specified game mode.
if (GetOnlineSession()->GetPartyMembers().Num() <= 1)
{
return true;
}
bool bResult = (GameModeType != EGameModeType::FFA);
UE_LOG_PLAYINGWITHPARTY(Log, TEXT("Validating to start matchmaking with party in %s game mode."), GameModeType == EGameModeType::FFA ? TEXT("Elimination") : TEXT("Team Deathmatch"));
// Notify cannot matchmaking using the specified game mode.
if (!bResult && GetPromptSubystem())
{
GetPromptSubystem()->PushNotification(PARTY_MATCHMAKING_SAFEGUARD_MESSAGE, FString(""));
}
return bResult;
} -
プレイヤーが Byte Wars のオンラインセッションに関連するユーザーインターフェース(UI)にアクセスしようとしたときに、これらのイベントが呼び出されるようにバインドします。これを行うには、サブシステムが初期化されたときに最初に呼び出される、事前定義された
Initialize()関数に以下のコードを追加します。void UPlayWithPartySubsystem_Starter::Initialize(FSubsystemCollectionBase& Collection)
{
// ...
// Add party validation to online session related UIs.
if (GetOnlineSession())
{
GetOnlineSession()->ValidateToStartSession.Unbind();
GetOnlineSession()->ValidateToStartSession.BindUObject(this, &ThisClass::ValidateToStartPartyGameSession);
GetOnlineSession()->ValidateToStartMatchmaking.Unbind();
GetOnlineSession()->ValidateToStartMatchmaking.BindUObject(this, &ThisClass::ValidateToStartPartyMatchmaking);
GetOnlineSession()->ValidateToJoinSession.Unbind();
GetOnlineSession()->ValidateToJoinSession.BindUObject(this, &ThisClass::ValidateToJoinPartyGameSession);
}
} -
サブシステムが非初期化されたときに関数をアンバインドします。事前定義された
Deinitialize()関数に以下のコードを追加します。void UPlayWithPartySubsystem_Starter::Deinitialize()
{
// ...
// Remove party validation to online session related UIs.
if (GetOnlineSession())
{
if (GetOnlineSession()->ValidateToStartSession.GetUObject() == this)
{
GetOnlineSession()->ValidateToStartSession.Unbind();
}
if (GetOnlineSession()->ValidateToStartMatchmaking.GetUObject() == this)
{
GetOnlineSession()->ValidateToStartMatchmaking.Unbind();
}
if (GetOnlineSession()->ValidateToJoinSession.GetUObject() == this)
{
GetOnlineSession()->ValidateToJoinSession.Unbind();
}
}
} -
プレイヤーが Byte Wars のオンラインセッションに関連する UI にアクセスしようとすると、パーティでのプレイに関連する機能を実行する前に、まず検証が行われます。これらの UI は、プレイヤーがマッチメイキングのために Quick Play にアクセスしたり、パーティセッションやマッチセッションを作成したり、ゲームセッションを閲覧したりするときのものです。
-
ValidateToStartPartyGameSession()関数は、プレイヤーが Play Online > Create A Session > Create Elimination および Play Online > Create Match Session > [任意のゲームモードボタン] > [任意のネットワークモードボタン] をクリックしたときに呼び出されます。 -
ValidateToJoinPartyGameSession()関数は、プレイヤーが Play Online > Browse Matches から Join ボタンをクリックしたときに呼び出されます。 -
ValidateToStartPartyMatchmaking()関数は、プレイヤーが Play Online > Quick Play > [任意のゲームモードボタン] > [任意のネットワークモードボタン] からマッチメイキングのために Server Type を選択したときに呼び出されます。
-
-
Quick Play > Elimination > [任意のネットワークモードボタン] では Cannot matchmake in elimination mode when in party、または Create Match Session > [任意のゲームモードボタン] > [任意のネットワークモードボタン] では Only Party Leader can start Online Session という通知が表示されます。
リソース
-
このチュートリアルセクションで使用されているファイルは、Unreal Engine Byte Wars GitHub リポジトリで入手できます。