AGSマッチメイキングでPhoton Multiplayerを使用する
注釈:本資料はAI技術を用いて翻訳されています。
概要
AccelByte Gaming Services(AGS)は、マルチプレイヤーネットワークルーム名に一意に生成されたセッションIDを使用しており、これによりPhoton Multiplayerを使用できます。これを可能にするために使用されるサービスは、AGS Authentication、Lobby(マッチメイキングwebsocketイベント用)、Matchmaking(マッチメイキングAPI用)、およびSession(ゲームセッション追跡用)です。
この記事では、PhotonがAGSとどのように連携するかについての情報と、統合方法の手順を提供します。
前提条件
この記事のすべての手順を完了するには、以下が必要です。
- AGS Authentication、Lobby、Matchmaking、およびSessionがすべてゲームに統合され、適切に設定されていること。
PhotonとAGSのフロー
PhotonがAGSとどのように連携するかを理解するには、以下のフロー図を参照してください。

認証
マッチメイキングに必要なAGS内のサービスを使用できるようにするには、プレイヤーが認証されてログインしている必要があります。これは、Userサービスラッパーを使用して行うことができます。
public void Login()
{
var userWrapper = AccelByteSDK.GetClientRegistry().GetApi().GetUser();
userWrapper.LoginWithDeviceId((Result<TokenData, OAuthError> result) =>
{
if (result.IsError)
{
Debug.Log($"Error- [{result.Error.error}]{result.Error.error_description}");
// ログインエラーを処理
}
// ログイン成功、フローを続行。
});
}
関連するLobbyイベントに接続して設定する
AGSマッチメイキングはイベントにwebsocketを使用します。websocket接続とイベントへのリスナーの追加は、AGS Lobbyサービスラッパーを通じて行われます。
認証成功直後にLobbyサービスに接続することを強くお勧めします。この方法は、競合状態を防ぎ、正確なCCUメトリクス追跡を確保するのに役立ちます。Lobby接続を確立するには、以下のコードを使用してください。
public void ConnectAndSetupLobby()
{
var lobbyWrapper = AccelByteSDK.GetClientRegistry().GetApi().GetLobby();
// ユーザーが正常にログインしたらすぐにlobbyサービスに接続することを強くお勧めします。
// これにより、他のサービスやlobbyイベントに関連する競合状態を回避でき、
// CCUメトリクスを追跡できます。
lobbyWrapper.Connect();
// StartMatchmaking()を呼び出す前に、lobbyWrapper.IsConnected == trueであることを確認してください
// また、イベント経由でStartMatchmakingをトリガーすることもできます
lobbyWrapper.Connected += () =>
{
StartMatchmaking();
}
// マッチメイキングイベント
lobbyWrapper.MatchmakingV2MatchmakingStarted += OnMatchmakingStarted;
lobbyWrapper.MatchmakingV2MatchFound += OnMatchFound;
lobbyWrapper.MatchmakingV2TicketExpired += OnTicketExpired;
lobbyWrapper.SessionV2InvitedUserToGameSession += OnReceivedSessionInvite;
}
マッチメイキングを開始する
マッチメイキングを開始するには、マッチメイキングチケットを作成する必要があります。これは、AGS Matchmakingサービスラッパーを使用して行うことができます。
public void StartMatchmaking()
{
var lobbyWrapper = AccelByteSDK.GetClientRegistry().GetApi().GetLobby();
if (!lobbyWrapper.IsConnected)
{
Debug.LogWarning("Lobby is not connected, unable to start matchmaking");
return;
}
var matchmakingWrapper = AccelByteSDK.GetClientRegistry().GetApi().GetMatchmakingV2();
var optionalParams = new MatchmakingV2CreateTicketRequestOptionalParams()
{
// プレイヤーがソロの場合はnullのままにします。
// プレイヤーがパーティーにいる場合は、ここにパーティーセッションIDを入力します。
sessionId = null,
// プレイヤーがゲームプレイオプションを選択/優先できるように
// 計画していない場合は、nullのままにします。
// ここに任意の値を入力でき、マッチメイキングは
// 同じ属性値を持つプレイヤーとマッチングを試みます。
attributes = new Dictionary<string, object>()
{
{ "map", 1 },
{ "difficulty", "normal" }
}
};
matchmakingWrapper.CreateMatchmakingTicket("yourMatchPoolName", optionalParams, result =>
{
if (result.IsError)
{
Debug.Log($"Error- [{result.Error.Code}] {result.Error.Message}");
// マッチメイキングAPIエラーをここで処理
}
// マッチメイキング開始、フローを続行。
});
}
マッチメイキングイベントコールバック経由でのPhoton統合
これらは、上記のAGS Lobbyマッチメイキングイベントのコールバックの推奨実装です。必要に応じて自由に拡張または変更できます。Photon統合は、プレイヤーがAGSゲームセッションに参加した後に行われます(マッチメイキングプロセスの終了、OnReceivedSessionInvite)。選択したPhotonフレームワークに応じて、ルーム名としてゲームセッションのIDを使用して作成または参加します。
private void OnMatchmakingStarted(Result<MatchmakingV2MatchmakingStartedNotification> result)
{
// パーティーリーダーがマッチメイキングを正常に開始したときに呼び出されます。
// 他のパーティーメンバーのセットアップをここで行います。
// (例:マッチメイキングが開始されたことをプレイヤーに通知、タイマーUIを表示するなど)
if (result.IsError)
{
Debug.Log($"Error- [{result.Error.Code}] {result.Error.Message}");
// マッチメイキングイベントエラーをここで処理
return;
}
}
private void OnMatchFound(Result<MatchmakingV2MatchFoundNotification> result)
{
// マッチが見つかったときに呼び出されます。
// セットアップ/準備をここで行います。
// (例:バックグラウンドでアセットをプリロード、マッチ発見UIを表示するなど)
if (result.IsError)
{
Debug.Log($"Error- [{result.Error.Code}] {result.Error.Message}");
// マッチメイキングイベントエラーをここで処理
return;
}
}
private void OnTicketExpired(Result<MatchmakingV2TicketExpiredNotification> result)
{
// チケットがマッチを見つけることなく設定された
// 有効期限タイムアウト時間に達したときに呼び出されます。
// ここでStartMatchmaking()を安全に再度呼び出して
// プロセスを自動的に再開できます(パーティーにいる場合はパーティーリーダーのみ)、
// またはマッチが見つからなかったことをプレイヤーに通知します(制限属性がある場合)。
if (result.IsError)
{
Debug.Log($"Error- [{result.Error.Code}] {result.Error.Message}");
// マッチメイキングイベントエラーをここで処理
return;
}
StartMatchmaking();
}
private void OnReceivedSessionInvite(Result<SessionV2GameInvitationNotification> result)
{
// マッチセッションが準備され、プレイヤーを参加に招待したときに呼び出されます。
// 結果のsessionIdをPhotonルームのルーム名として
// 使用して参加できます。
if (result.IsError)
{
Debug.Log($"Error- [{result.Error.Code}] {result.Error.Message}");
// マッチメイキングイベントエラーをここで処理
return;
}
// これをどこか永続的な場所に保存します
// ゲーム終了後またはプレイヤーが退出/切断した後にセッションをクリーンアップするために後で使用されます。
string sessionId = result.Value.sessionId;
var sessionWrapper = AccelByteSDK.GetClientRegistry().GetApi().GetSession();
sessionWrapper.JoinGameSession(sessionId, joinResult =>
{
if (joinResult.IsError)
{
Debug.Log($"Error- [{result.Error.Code}] {result.Error.Message}");
// セッションAPIエラーをここで処理
return;
}
// セッション参加成功、Photonネットワーキングを続行。
// Photon PUN:
// PhotonNetwork.JoinOrCreateRoom(sessionId, roomOptions, typedLobby);
// Photon Realtime / Quantum:
// loadBalancingClient.OpJoinOrCreateRoom(new EnterRoomParams {
// RoomName = accelByteSessionIdFromLobbyEvent
// });
// Photon Fusion:
// networkRunner.StartGame(new StartGameArgs {
// SessionName = accelByteSessionIdFromLobbyEvent
// });
});
}
セッションのクリーンアップ
ゲームが終了したとき、またはプレイヤーが退出/切断した場合は、クリーンアップのためにAccelByteセッションサービスラッパーのleaveも必ず呼び出してください。
private void OnGameEnd()
{
var sessionWrapper = AccelByteSDK.GetClientRegistry().GetApi().GetSession();
sessionWrapper.LeaveGameSession("sessionIdFromMatchmaking", result =>
{
if (result.IsError)
{
Debug.Log($"Error- [{result.Error.Code}] {result.Error.Message}");
// セッションAPIエラーをここで処理
return;
}
});
}
Lobby切断
一度接続したら、ユーザーがログアウトするとき、またはゲームが終了またはクラッシュするときにのみLobbyサービスを切断してください。このコードを使用します。
User userWrapper = AccelByteSDK.GetClientRegistry().GetApi().GetUser();
Lobby lobbyWrapper = AccelByteSDK.GetClientRegistry().GetApi().GetLobby();
void Logout()
{
userWrapper.Logout(logoutResult =>
{
if (logoutResult.IsError)
{
// ログアウトエラーをここで処理
return;
}
lobby.Disconnect();
});
}
void OnApplicationQuit()
{
lobbyWrapper.Disconnect();
}