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

SDKを使用してパーティーを設定する - パーティーの紹介 - (Unityモジュール)

Last updated on February 4, 2026

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

オンラインセッションの展開

パーティーの作成は、本質的に「パーティー」タイプの新しいセッションを作成することであるため、パーティーの管理はゲームセッションの管理と似ています。このセクションでは、AccelByte Gaming Services (AGS) SDKを使用して、パーティーの基本機能を設定する方法を学びます。Byte Warsには、PartyEssentialsWrapper_Starterクラスで定義された完成したラッパーがあります。このチュートリアルでは、そのラッパーのスターターバージョンを使用して、機能をゼロから統合します。

スターターパックの内容

このチュートリアルに従うには、PartyEssentialsWrapper_Starterというスターターラッパークラスを使用します。このクラスは、次のファイルで定義されているAccelByteWarsOnlineSessionという名前のルート親クラスを継承しています。

  • C#ファイル: Assets/Resources/Modules/Play/OnlineSessionUtils/Scripts/AccelByteWarsOnlineSession.cs

PartyEssentialsWrapper_Starterクラスは、以下のファイルで定義されています。

  • C#ファイル: Assets/Resources/Modules/Play/PartyEssentials/Scripts/PartyEssentialsWrapper_Starter.cs

また、以下のファイルで定義されたヘルパー定数変数と構造体を含むモデルクラスもあります。

  • C#ファイル: Assets/Resources/Modules/Play/PartyEssentials/Scripts/PartyEssentialsModels.cs

AccelByteWarsOnlineSessionのルート親クラスには、次のような事前定義されたヘルパーコンポーネントがいくつか含まれています。

  • AGS SDKインターフェースを参照するためのヘルパー変数。これらの変数は初期化中に割り当てられます。

    protected static User User;
    protected static Lobby Lobby;
    protected static Session Session;

    protected virtual void Awake()
    {
    ...
    User ??= AccelByteSDK.GetClientRegistry().GetApi().GetUser();
    Lobby ??= AccelByteSDK.GetClientRegistry().GetApi().GetLobby();
    Session ??= AccelByteSDK.GetClientRegistry().GetApi().GetSession();
    ...
    }
  • アクティブなパーティーセッションを追跡するための静的ヘルパープロパティ:

    public static SessionV2PartySession CachedParty { get; protected set; } = null;
  • パーティーセッションが更新されたときにブロードキャストするデリゲート。新しいパーティーメンバーが参加したとき、パーティーメンバーが退出したとき、または新しいパーティーリーダーが昇格したときなどに使用されます。このデリゲートは後でUI統合に使用されます。

    public static Action OnPartySessionUpdated = delegate { };

PartyEssentialsModelsクラスには、以下のようないくつかのヘルパーがあります。

  • パーティーセッション設定を定義する定数。

    public static readonly string PartySessionTemplateName = "unity-party";
    public static readonly int PartyMaxMembers = 4;
  • パーティー関連のポップアップメッセージを表示するための文字列。

    public static readonly string PartyPopUpMessage = "Party";
    public static readonly string JoinNewPartyConfirmationMessage = "Leave Current Party and Join a New One?";

    public static readonly string SuccessSendPartyInviteMessage = "Party Invitation Sent";
    public static readonly string FailedSendPartyInviteMessage = "Failed to Send Party Invitation";

    public static readonly string PartyNewLeaderMessage = "Is Now the Party Leader";
    public static readonly string PartyMemberJoinedMessage = "Joined the Party";
    public static readonly string PartyMemberLeftMessage = "Left the Party";
    public static readonly string PartyInviteReceivedMessage = "Invites You to Party";
    public static readonly string PartyInviteRejectedMessage = "Rejected Your Party Invite";
    public static readonly string KickedFromPartyMessage = "Kicked From the Party";

    public static readonly string AcceptPartyInviteMessage = "Accept";
    public static readonly string RejectPartyInviteMessage = "Reject";
  • パーティーセッション情報とパーティーメンバーのリストで構成されるパーティー詳細情報を構築するための構造体。

    public struct PartyDetailsModel
    {
    public SessionV2PartySession PartySession;
    public AccountUserPlatformData[] MemberUserInfos;
    }

パーティー作成の実装

このセクションでは、新しいパーティーセッションを作成する方法を学びます。

  1. PartyEssentialsWrapper_Starterクラスを開きます。次に、以下の新しい関数を作成して、参加可能性を招待のみに設定した新しいパーティーリクエストを作成します。リクエストが完了すると、この関数はキャッシュされたパーティーセッションを更新し、割り当てられたデリゲートを呼び出してパーティー作成結果をブロードキャストします。

    public void CreateParty(ResultCallback<SessionV2PartySession> onComplete = null)
    {
    SessionV2PartySessionCreateRequest request = new SessionV2PartySessionCreateRequest()
    {
    configurationName = PartyEssentialsModels.PartySessionTemplateName,
    joinability = SessionV2Joinability.INVITE_ONLY
    };

    Session.CreateParty(request, (Result<SessionV2PartySession> result) =>
    {
    if (result.IsError)
    {
    BytewarsLogger.LogWarning($"Failed to create party. Error {result.Error.Code}: {result.Error.Message}");
    }
    else
    {
    CachedParty = result.Value;
    BytewarsLogger.Log($"Success to create party. Party id: {CachedParty.id}");
    AccelByteWarsOnlineSession.OnPartySessionUpdated?.Invoke();
    }

    onComplete?.Invoke(result);
    });
    }
  2. これで完了です!新しいパーティーを作成する関数を作成しました。

パーティー退出の実装

このセクションでは、パーティーセッションから退出する方法を学びます。

  1. PartyEssentialsWrapper_Starterクラスを開きます。次に、以下の新しい関数を作成して、現在参加しているパーティーセッションが存在する場合は退出します。リクエストが完了すると、この関数はキャッシュされたパーティーセッションをリセットし、割り当てられたデリゲートを呼び出して結果をブロードキャストします。

    public void LeaveParty(ResultCallback onComplete = null)
    {
    if (CachedParty == null)
    {
    const string errorMessage = "Failed to leave party. Current party session is null.";
    BytewarsLogger.LogWarning(errorMessage);
    onComplete?.Invoke(Result.CreateError(ErrorCode.None, errorMessage));
    return;
    }

    Session.LeaveParty(CachedParty.id, (Result result) =>
    {
    if (result.IsError)
    {
    BytewarsLogger.LogWarning($"Failed to leave party. Error {result.Error.Code}: {result.Error.Message}");
    }
    else
    {
    BytewarsLogger.Log($"Success to leave party. Party id: {CachedParty.id}");
    CachedParty = null;
    AccelByteWarsOnlineSession.OnPartySessionUpdated?.Invoke();
    }

    onComplete?.Invoke(result);
    });
    }
  2. これで完了です!パーティーから退出する関数を作成しました。

パーティー詳細取得の実装

このセクションでは、パーティーとそのメンバーの詳細を取得する方法を学びます。

  1. PartyEssentialsWrapper_Starterクラスを開きます。次に、以下の新しい関数を作成して、パーティー詳細を取得するリクエストを送信します。パーティー詳細を受信した後、この関数は各メンバーの情報をクエリして、プレイヤー名やアバターなどの詳細を取得します。次に、この関数はパーティー詳細とメンバー詳細をPartyDetailsModelという名前のカスタム構造体に統合し、割り当てられたデリゲートを呼び出して返します。

    public void GetPartyDetails(ResultCallback<PartyEssentialsModels.PartyDetailsModel> onComplete = null) 
    {
    if (CachedParty == null)
    {
    const string errorMessage = "Failed to get party details. Current party session is null.";
    BytewarsLogger.LogWarning(errorMessage);
    onComplete?.Invoke(Result<PartyEssentialsModels.PartyDetailsModel>.CreateError(ErrorCode.None, errorMessage));
    return;
    }

    Session.GetPartyDetails(CachedParty.id, (Result<SessionV2PartySession> result) =>
    {
    if (result.IsError)
    {
    string errorMessage = $"Failed to get party details. Error {result.Error.Code}: {result.Error.Message}";
    BytewarsLogger.LogWarning(errorMessage);
    onComplete?.Invoke(Result<PartyEssentialsModels.PartyDetailsModel>.CreateError(ErrorCode.None, errorMessage));
    return;
    }

    SessionV2PartySession partySession = result.Value;
    string[] memberIds = result.Value.members.Where(x => x.StatusV2 == SessionV2MemberStatus.JOINED).Select(x => x.id).ToArray();
    if (memberIds.Length <= 0)
    {
    CachedParty = null;
    string errorMessage = $"Failed to get party details. No party active party members.";
    BytewarsLogger.LogWarning(errorMessage);
    onComplete?.Invoke(Result<PartyEssentialsModels.PartyDetailsModel>.CreateError(ErrorCode.None, errorMessage));
    return;
    }

    User.GetUserOtherPlatformBasicPublicInfo("ACCELBYTE", memberIds, (Result<AccountUserPlatformInfosResponse> userDataResult) =>
    {
    if (userDataResult.IsError)
    {
    string errorMessage = $"Failed to get party details. Error {userDataResult.Error.Code}: {userDataResult.Error.Message}";
    BytewarsLogger.LogWarning(errorMessage);
    onComplete?.Invoke(Result<PartyEssentialsModels.PartyDetailsModel>.CreateError(ErrorCode.None, errorMessage));
    return;
    }

    CachedParty = partySession;
    BytewarsLogger.Log($"Success to get party details. Party id: {CachedParty.id}");

    PartyEssentialsModels.PartyDetailsModel partyDetails = new PartyEssentialsModels.PartyDetailsModel
    {
    PartySession = CachedParty,
    MemberUserInfos = userDataResult.Value.Data
    };
    onComplete?.Invoke(Result<PartyEssentialsModels.PartyDetailsModel>.CreateOk(partyDetails));
    });
    });
    }
  2. これで完了です!パーティー詳細を取得する関数を作成しました。

パーティー招待送信の実装

このセクションでは、パーティー招待を送信する方法を学びます。

  1. PartyEssentialsWrapper_Starterクラスを開きます。次に、以下の新しい関数を作成して、対象プレイヤーにパーティー招待を送信します。この関数では、送信者がまだパーティーに参加していない場合、招待を送信する前に新しいパーティーを作成するリクエストを最初に行います。パーティー招待を送信するリクエストが完了すると、関数は割り当てられたデリゲートを呼び出して結果をブロードキャストし、画面に通知を表示します。

    public void SendPartyInvite(string inviteeUserId, ResultCallback onComplete = null) 
    {
    // If not in any party, create a new one first.
    if (CachedParty == null)
    {
    CreateParty((Result<SessionV2PartySession> result) =>
    {
    if (result.IsError)
    {
    BytewarsLogger.LogWarning($"Cannot send a party invitation. Failed to create a new party.");
    onComplete?.Invoke(Result.CreateError(result.Error));
    return;
    }

    SendPartyInvite(inviteeUserId, onComplete);
    });
    return;
    }

    Session.InviteUserToParty(CachedParty.id, inviteeUserId, (Result result) =>
    {
    if (result.IsError)
    {
    BytewarsLogger.LogWarning($"Failed to send a party invitation. Invitee user ID: {inviteeUserId}. Error {result.Error.Code}: {result.Error.Message}");
    }
    else
    {
    BytewarsLogger.Log($"Success to send a party invitation. Invitee user ID: {inviteeUserId}.");
    }

    // Display push notification.
    MenuManager.Instance.PushNotification(new PushNotificationModel
    {
    Message = result.IsError ? PartyEssentialsModels.FailedSendPartyInviteMessage : PartyEssentialsModels.SuccessSendPartyInviteMessage
    });

    onComplete?.Invoke(result);
    });
    }
  2. これで完了です!パーティー招待を送信する関数を作成しました。

パーティー招待承認の実装

このセクションでは、パーティーに参加してパーティー招待を承認する方法を学びます。

  1. PartyEssentialsWrapper_Starterクラスを開きます。次に、以下の新しい関数を作成して、パーティーIDでパーティーに参加します。この関数では、プレイヤーがすでにパーティーに参加している場合、新しいパーティーに参加する前に現在のパーティーから退出するリクエストを最初に行います。新しいパーティーに参加するリクエストが完了すると、関数はキャッシュされたパーティーセッションを更新し、割り当てられたデリゲートを呼び出して結果をブロードキャストします。

    public void JoinParty(string partyId, ResultCallback<SessionV2PartySession> onComplete = null) 
    {
    // Leave current party first.
    if (CachedParty != null)
    {
    LeaveParty((Result result) =>
    {
    if (result.IsError)
    {
    BytewarsLogger.LogWarning($"Cannot join a new party. Failed to leave current party. Error {result.Error.Code}: {result.Error.Message}");
    onComplete.Invoke(Result<SessionV2PartySession>.CreateError(result.Error));
    return;
    }

    JoinParty(partyId, onComplete);
    });
    return;
    }

    Session.JoinParty(partyId, (Result<SessionV2PartySession> result) =>
    {
    if (result.IsError)
    {
    BytewarsLogger.LogWarning($"Failed to join party. Party Id: {partyId}. Error {result.Error.Code}: {result.Error.Message}");
    }
    else
    {
    CachedParty = result.Value;
    BytewarsLogger.Log($"Success to join party. Party id: {CachedParty.id}");
    }

    onComplete?.Invoke(result);
    });
    }
  2. これで完了です!パーティーに参加してパーティー招待を承認する関数を作成しました。

パーティー招待拒否の実装

このセクションでは、パーティー招待を拒否する方法を学びます。

  1. PartyEssentialsWrapper_Starterクラスを開きます。次に、以下の新しい関数を作成して、パーティー招待を拒否します。リクエストが完了すると、関数は割り当てられたデリゲートを呼び出して結果をブロードキャストします。

    public void RejectPartyInvite(string partyId, ResultCallback onComplete = null) 
    {
    Session.RejectPartyInvitation(partyId, (Result result) =>
    {
    if (result.IsError)
    {
    BytewarsLogger.LogWarning($"Failed to reject a party invitation. Error {result.Error.Code}: {result.Error.Message}");
    }
    else
    {
    BytewarsLogger.Log($"Success to reject a party invitation.");
    }

    onComplete?.Invoke(result);
    });
    }
  2. 次に、招待が拒否されたときに呼び出されるコールバック関数を作成します。これは送信者側でトリガーされます。この関数は拒否情報をクエリし、通知として表示します。

    private void OnPartyInviteRejected(Result<SessionV2PartyInvitationRejectedNotification> result)
    {
    if (result.IsError)
    {
    BytewarsLogger.LogWarning($"Failed to handle on-party invitation rejected event. Error {result.Error.Code}: {result.Error.Message}");
    return;
    }

    string rejecterId = result.Value.rejectedId;
    BytewarsLogger.Log($"Party invitation is rejected by user: {rejecterId}");

    // Display push notification.
    User.GetUserOtherPlatformBasicPublicInfo("ACCELBYTE", new string[] { rejecterId }, (Result<AccountUserPlatformInfosResponse> userDataResult) =>
    {
    AccountUserPlatformData rejecterInfo = userDataResult.IsError ? null : userDataResult.Value.Data[0];

    string rejecterName = userDataResult.IsError ?
    AccelByteWarsUtility.GetDefaultDisplayNameByUserId(rejecterId) :
    AccelByteWarsOnlineUtility.GetDisplayName(rejecterInfo);
    string rejecterAvatarUrl = userDataResult.IsError ? string.Empty : rejecterInfo.AvatarUrl;

    MenuManager.Instance.PushNotification(new PushNotificationModel
    {
    Message = $"{rejecterName} {PartyEssentialsModels.PartyInviteRejectedMessage}",
    IconUrl = rejecterAvatarUrl,
    UseDefaultIconOnEmpty = true
    });
    });
    }
  3. 次に、ラッパーが初期化されたときにコールバック関数をバインドする必要があります。これを行うには、事前定義されたOnEnable()関数に以下のコードを追加します。

    private void OnEnable()
    {
    ...
    Lobby.SessionV2UserRejectedPartyInvitation += OnPartyInviteRejected;
    }
  4. 最後に、ラッパーが非初期化されたときにコールバック関数をアンバインドする必要もあります。これを行うには、事前定義されたOnDisable()関数に以下のコードを追加します。

    private void OnDisable()
    {
    ...
    Lobby.SessionV2UserRejectedPartyInvitation -= OnPartyInviteRejected;
    }
  5. これで完了です!パーティー招待を拒否する関数と、招待拒否イベントを処理する機能を作成しました。

受信したパーティー招待の処理

前のセクションでは、パーティー招待を承認および拒否する関数を作成しました。このセクションでは、受信したパーティー招待イベントを処理する方法を学び、プレイヤーが招待を承認するか拒否するかを決定できるようにします。

  1. PartyEssentialsWrapper_Starterクラスを開きます。次に、以下の新しいヘルパー関数を作成して、プレイヤーがすでにパーティーに参加している場合に、本当にパーティー招待を承認したいかどうかを尋ねる確認プロンプトを表示します。

    private void DisplayJoinPartyConfirmation(SessionV2PartyInvitationNotification partyInvite) 
    {
    // Join the party if not in any party yet.
    bool isAloneInParty = CachedParty == null || CachedParty?.members?.Where(m => m.StatusV2 == SessionV2MemberStatus.JOINED).ToArray().Length <= 1;
    if (isAloneInParty)
    {
    JoinParty(partyInvite.partyId);
    return;
    }

    // Show confirmation to leave current party and join the new party.
    MenuManager.Instance.PromptMenu.ShowPromptMenu(
    PartyEssentialsModels.PartyPopUpMessage,
    PartyEssentialsModels.JoinNewPartyConfirmationMessage,
    PartyEssentialsModels.RejectPartyInviteMessage,
    () => { RejectPartyInvite(partyInvite.partyId); },
    PartyEssentialsModels.AcceptPartyInviteMessage,
    () => { JoinParty(partyInvite.partyId); });
    }
  2. 次に、パーティー招待を受信したときに呼び出される新しいコールバック関数を作成します。この関数は招待送信者の情報をクエリし、プレイヤーが承認または拒否するためのボタンを含む通知を表示します。プレイヤーが承認を選択した場合、先ほど作成したDisplayJoinPartyConfirmation()関数を呼び出して、プレイヤーがすでにパーティーに参加している場合に本当に参加したいかどうかを再確認します。

    private void OnPartyInviteReceived(Result<SessionV2PartyInvitationNotification> result)
    {
    if (result.IsError)
    {
    BytewarsLogger.LogWarning($"Failed to handle received party invitation. Error {result.Error.Code}: {result.Error.Message}");
    return;
    }

    string senderId = result.Value.senderId;
    string partyId = result.Value.partyId;

    BytewarsLogger.Log($"Receives party invitation from {result.Value.senderId}");

    // Display push notification.
    User.GetUserOtherPlatformBasicPublicInfo("ACCELBYTE", new string[] { senderId }, (Result<AccountUserPlatformInfosResponse> userDataResult) =>
    {
    AccountUserPlatformData senderInfo = userDataResult.IsError ? null : userDataResult.Value.Data[0];

    string senderName = userDataResult.IsError ?
    AccelByteWarsUtility.GetDefaultDisplayNameByUserId(senderId) :
    AccelByteWarsOnlineUtility.GetDisplayName(senderInfo);
    string senderAvatarUrl = userDataResult.IsError ? string.Empty : senderInfo.AvatarUrl;

    MenuManager.Instance.PushNotification(new PushNotificationModel
    {
    Message = $"{senderName} {PartyEssentialsModels.PartyInviteReceivedMessage}",
    IconUrl = senderAvatarUrl,
    UseDefaultIconOnEmpty = true,
    ActionButtonTexts = new string[] { PartyEssentialsModels.AcceptPartyInviteMessage, PartyEssentialsModels.RejectPartyInviteMessage },
    ActionButtonCallback = (PushNotificationActionResult actionResult) =>
    {
    switch (actionResult)
    {
    // Show accept party invitation confirmation.
    case PushNotificationActionResult.Button1:
    DisplayJoinPartyConfirmation(result.Value);
    break;
    // Reject party invitation.
    case PushNotificationActionResult.Button2:
    RejectPartyInvite(result.Value.partyId);
    break;
    }
    }
    });
    });
    }
  3. 次に、ラッパーが初期化されたときにコールバック関数をバインドする必要があります。これを行うには、事前定義されたOnEnable()関数に以下のコードを追加します。

    private void OnEnable()
    {
    ...
    Lobby.SessionV2InvitedUserToParty += OnPartyInviteReceived;
    }
  4. 最後に、ラッパーが非初期化されたときにコールバック関数をアンバインドする必要もあります。これを行うには、事前定義されたOnDisable()関数に以下のコードを追加します。

    private void OnDisable()
    {
    ...
    Lobby.SessionV2InvitedUserToParty -= OnPartyInviteReceived;
    }
  5. これで完了です!受信したパーティー招待イベントを処理し、プレイヤーに確認プロンプトを表示して、招待を承認または拒否できるようにしました。

パーティーメンバーのキックの実装

このセクションでは、パーティーからメンバーをキックする方法を学びます。

  1. PartyEssentialsWrapper_Starterクラスを開きます。次に、以下の新しい関数を作成して、現在のパーティーからメンバーをキックします。この関数はパーティーリーダーのみが呼び出すことができます。リクエストが完了すると、関数は割り当てられたデリゲートを呼び出して結果をブロードキャストします。

    public void KickPlayerFromParty(string targetUserId, ResultCallback<SessionV2PartySessionKickResponse> onComplete = null) 
    {
    if (CachedParty == null)
    {
    const string errorMessage = "Failed to kick player from party. Current party session is null.";
    BytewarsLogger.LogWarning(errorMessage);
    onComplete?.Invoke(Result<SessionV2PartySessionKickResponse>.CreateError(ErrorCode.None, errorMessage));
    return;
    }

    Session.KickUserFromParty(CachedParty.id, targetUserId, (Result<SessionV2PartySessionKickResponse> result) =>
    {
    if (result.IsError)
    {
    BytewarsLogger.LogWarning($"Failed to kick player from party. Target user: {targetUserId}. Error {result.Error.Code}: {result.Error.Message}");
    }
    else
    {
    BytewarsLogger.LogWarning($"Success to kick player from party. Target user: {targetUserId}");
    }

    onComplete?.Invoke(result);
    });
    }
  2. 次に、メンバーがパーティーからキックされたときに呼び出されるコールバック関数を作成します。これはキックされたメンバー側でトリガーされます。この関数は画面に通知を表示します。

    private void OnKickedFromParty(Result<SessionV2PartyUserKickedNotification> result)
    {
    if (result.IsError)
    {
    BytewarsLogger.LogWarning($"Failed to handle on-kicked from party event. Error {result.Error.Code}: {result.Error.Message}");
    return;
    }

    BytewarsLogger.Log($"Kicked from party. Party id: {result.Value.partyId}");
    CachedParty = null;

    // Display push notification.
    MenuManager.Instance.PushNotification(new PushNotificationModel
    {
    Message = $"You are {PartyEssentialsModels.KickedFromPartyMessage}"
    });

    AccelByteWarsOnlineSession.OnPartySessionUpdated?.Invoke();
    }
  3. 次に、ラッパーが初期化されたときにコールバック関数をバインドする必要があります。これを行うには、事前定義されたOnEnable()関数に以下のコードを追加します。

    private void OnEnable()
    {
    ...
    Lobby.SessionV2UserKickedFromParty += OnKickedFromParty;
    }
  4. 最後に、ラッパーが非初期化されたときにコールバック関数をアンバインドする必要もあります。これを行うには、事前定義されたOnDisable()関数に以下のコードを追加します。

    private void OnDisable()
    {
    ...
    Lobby.SessionV2UserKickedFromParty -= OnKickedFromParty;
    }
  5. これで完了です!パーティーからメンバーをキックする関数と、パーティーからキックされたイベントを処理する機能を作成しました。

新しいパーティーリーダーの昇格の実装

このセクションでは、パーティーからメンバーをキックする方法を学びます。

  1. PartyEssentialsWrapper_Starterクラスを開きます。次に、以下の新しい関数を作成して、メンバーを新しいパーティーリーダーとして昇格させます。この関数は現在のパーティーリーダーのみが呼び出すことができます。リクエストが完了すると、関数は割り当てられたデリゲートを呼び出して結果をブロードキャストします。

    public void PromotePartyLeader(string targetUserId, ResultCallback<SessionV2PartySession> onComplete = null) 
    {
    if (CachedParty == null)
    {
    const string errorMessage = "Failed to promote a new party leader. Current party session is null.";
    BytewarsLogger.LogWarning(errorMessage);
    onComplete?.Invoke(Result<SessionV2PartySession>.CreateError(ErrorCode.None, errorMessage));
    return;
    }

    Session.PromoteUserToPartyLeader(CachedParty.id, targetUserId, (Result<SessionV2PartySession> result) =>
    {
    if (result.IsError)
    {
    BytewarsLogger.LogWarning($"Failed to promote new party leader. Target user id: {targetUserId}. Error {result.Error.Code}: {result.Error.Message}");
    }
    else
    {
    BytewarsLogger.Log($"Success to promote a new party leader. New leader user id: {CachedParty.leaderId}");
    }

    onComplete?.Invoke(result);
    });
    }
  2. これで完了です!新しいパーティーリーダーを昇格させる関数を作成しました。

パーティーセッション更新の処理

パーティーセッションは、パーティー関連のイベントが発生したときに更新されます。たとえば、新しいメンバーが参加または退出したとき、新しいパーティーリーダーが設定されたとき、メンバーがキックされたときなどです。このセクションでは、これらのイベントを処理してキャッシュされたパーティーセッションを更新し、UIに最新のパーティー情報を表示できるようにする方法を学びます。

  1. PartyEssentialsWrapper_Starterクラスを開きます。次に、メンバーリストが変更されたときやパーティーリーダーが変更されたときなど、パーティーセッションが更新されたときに呼び出される新しいコールバック関数を作成します。この関数は、パーティーリーダーが変更された場合に画面に通知を表示します。次に、OnPartyUpdateDelegateヘルパーデリゲートを呼び出してイベントをブロードキャストします。

    private void OnPartyUpdated(Result<SessionV2PartySessionUpdatedNotification> result)
    {
    if (result.IsError)
    {
    BytewarsLogger.LogWarning($"Failed to handle on-party updated event. Error {result.Error.Code}: {result.Error.Message}");
    return;
    }

    BytewarsLogger.Log("Party update received.");
    SessionV2PartySessionUpdatedNotification partyUpdateNotif = result.Value;

    // Display push notification regarding new party leader.
    if (CachedParty.leaderId != partyUpdateNotif.leaderId)
    {
    string newLeaderId = partyUpdateNotif.leaderId;

    User.GetUserOtherPlatformBasicPublicInfo("ACCELBYTE", new string[] { newLeaderId }, (Result<AccountUserPlatformInfosResponse> userDataResult) =>
    {
    AccountUserPlatformData newLeaderInfo = userDataResult.IsError ? null : userDataResult.Value.Data[0];

    string leaderName = userDataResult.IsError ?
    AccelByteWarsUtility.GetDefaultDisplayNameByUserId(newLeaderId) :
    AccelByteWarsOnlineUtility.GetDisplayName(newLeaderInfo);
    string leaderAvatarUrl = userDataResult.IsError ? string.Empty : newLeaderInfo.AvatarUrl;

    MenuManager.Instance.PushNotification(new PushNotificationModel
    {
    Message = $"{leaderName} {PartyEssentialsModels.PartyNewLeaderMessage}",
    IconUrl = leaderAvatarUrl,
    UseDefaultIconOnEmpty = true
    });
    });
    }

    // Update cached party session data.
    CachedParty.id = partyUpdateNotif.id;
    CachedParty.namespace_ = partyUpdateNotif.namespace_;
    CachedParty.members = partyUpdateNotif.members;
    CachedParty.attributes = partyUpdateNotif.attributes;
    CachedParty.createdAt = partyUpdateNotif.createdAt;
    CachedParty.updatedAt = partyUpdateNotif.updatedAt;
    CachedParty.configuration = partyUpdateNotif.configuration;
    CachedParty.version = partyUpdateNotif.version;
    CachedParty.leaderId = partyUpdateNotif.leaderId;
    CachedParty.createdBy = partyUpdateNotif.createdBy;

    AccelByteWarsOnlineSession.OnPartySessionUpdated?.Invoke();
    }
  2. 前述のパーティー更新イベントはメンバーリストが変更されたときにも呼び出されますが、詳細(誰がキックされたか、誰が参加しているか、誰が退出しているかなど)は含まれていません。したがって、パーティーメンバーリストが変更されたときに呼び出される新しいコールバック関数を作成する必要があります。この関数はメンバーの変更ステータスを収集し、変更ステータスに基づいて画面に通知を表示します。次に、OnPartyUpdateDelegateヘルパーデリゲートを呼び出してイベントをブロードキャストします。

    private void OnPartyMemberChanged(Result<SessionV2PartyMembersChangedNotification> result)
    {
    if (result.IsError)
    {
    BytewarsLogger.LogWarning($"Failed to handle on-party member changed event. Error {result.Error.Code}: {result.Error.Message}");
    return;
    }

    // Update cached party session data.
    SessionV2PartyMembersChangedNotification changeNotif = result.Value;
    CachedParty = changeNotif.session;

    // Collect changed member status and their user ids.
    Dictionary<string, SessionV2MemberStatus> updatedMemberStatus = new Dictionary<string, SessionV2MemberStatus>();
    if (changeNotif.joinerId != null)
    {
    updatedMemberStatus.TryAdd(changeNotif.joinerId, SessionV2MemberStatus.JOINED);
    }
    if (changeNotif.ImpactedUserIds != null)
    {
    if (changeNotif.ImpactedUserIds.LeftUserIds != null)
    {
    foreach (string leftMember in changeNotif.ImpactedUserIds.LeftUserIds)
    {
    updatedMemberStatus.TryAdd(leftMember, SessionV2MemberStatus.LEFT);
    }
    }
    if (changeNotif.ImpactedUserIds.KickedUserIds != null)
    {
    foreach (string kickedMember in changeNotif.ImpactedUserIds.KickedUserIds)
    {
    updatedMemberStatus.TryAdd(kickedMember, SessionV2MemberStatus.KICKED);
    }
    }
    }

    // Query user information and display the push notification based on member status.
    if (updatedMemberStatus.Count > 0)
    {
    User.GetUserOtherPlatformBasicPublicInfo("ACCELBYTE", updatedMemberStatus.Keys.ToArray(), (Result<AccountUserPlatformInfosResponse> userDataResult) =>
    {
    if (userDataResult.IsError)
    {
    BytewarsLogger.LogWarning(
    $"Failed to handle on-party member changed event. " +
    $"Error {userDataResult.Error.Code}: {userDataResult.Error.Message}");
    return;
    }

    foreach (AccountUserPlatformData memberInfo in userDataResult.Value.Data)
    {
    if (!updatedMemberStatus.ContainsKey(memberInfo.UserId))
    {
    continue;
    }

    string memberName = AccelByteWarsOnlineUtility.GetDisplayName(memberInfo);
    string pushNotifMessage = string.Empty;
    switch (updatedMemberStatus[memberInfo.UserId])
    {
    case SessionV2MemberStatus.JOINED:
    pushNotifMessage = $"{memberName} {PartyEssentialsModels.PartyMemberJoinedMessage}";
    break;
    case SessionV2MemberStatus.LEFT:
    pushNotifMessage = $"{memberName} {PartyEssentialsModels.PartyMemberLeftMessage}";
    break;
    case SessionV2MemberStatus.KICKED:
    pushNotifMessage = $"{memberName} {PartyEssentialsModels.KickedFromPartyMessage}";
    break;
    }

    MenuManager.Instance.PushNotification(new PushNotificationModel
    {
    Message = pushNotifMessage,
    IconUrl = memberInfo.AvatarUrl,
    UseDefaultIconOnEmpty = true
    });
    }
    });
    }

    AccelByteWarsOnlineSession.OnPartySessionUpdated?.Invoke();
    }
  3. 次に、ラッパーが初期化されたときにこれらのコールバック関数をバインドする必要があります。これを行うには、事前定義されたOnEnable()関数に以下のコードを追加します。

    private void OnEnable()
    {
    ...
    Lobby.SessionV2PartyUpdated += OnPartyUpdated;
    Lobby.SessionV2PartyMemberChanged += OnPartyMemberChanged;
    }
  4. 最後に、ラッパーが非初期化されたときにこれらのコールバック関数をアンバインドする必要もあります。これを行うには、事前定義されたOnDisable()関数に以下のコードを追加します。

    private void OnDisable()
    {
    ...
    Lobby.SessionV2PartyUpdated -= OnPartyUpdated;
    Lobby.SessionV2PartyMemberChanged -= OnPartyMemberChanged;
    }
  5. これで完了です!画面に通知を表示してパーティー更新イベントを処理し、後でUIに最新のパーティー情報を表示できるようにイベントをブロードキャストしました。

リソース