Last Updated: 11/8/2022, 8:40:17 AM

# AccelByte Cloud P2P for Unity

# Overview

The AccelByte Cloud Peer-to-Peer (P2P) for Unity allows players to conveniently establish peer-to-peer connections across private networks through the AccelByte Turn Server with AccelByteNetworkTransportManager as the main layer. P2P uses the Unity.Netcode.NetworkTransport interface with some specific initialization to allow it to run using the AccelByte service. After it has been initialized, the usage is straightforward and follows the Unity Netcode for Game Object (opens new window).

# Prerequisites

NOTE

AccelByte Cloud currently supports Unity version 2020.2 and upwards for P2P networking.

# Installation

  1. Open your Unity project, then open the Package Manager.

  2. Add Netcode for GameObjects package from the Unity resource and direct it to the AccelByte Cloud Unity SDK and AccelByte Networking Plugin.

  3. Add these additional entries to your assembly definition:

    p2p-unity

# Configuration

  1. Include these headers in your script:

    using Unity.WebRTC;
    using AccelByte.Api;
    using AccelByte.Core;
    using AccelByte.Models;
    
  2. Finish setting up multiple environments (opens new window).

  3. Open Unity editor.

  4. Open the AccelByte menu and click the Edit settings.

  5. Tick Use TURN Manager.

  6. Fill in the TURN Server Username and Server Secret.

    p2p-unity

    "UseTurnManager": true,
    "TurnServerSecret": "ENVIRONMENT_TURN_SECRET",
    "TurnServerUsername": "ENVIRONMENT_TURN_USERNAME",
    

# ApiClient

  1. Create an API client for each player.

    ApiClient apiClient = MultiRegistry.GetApiClient(localPlayerNumber);
        //localPlayerNumber can be filled with any unique string identifier for each local user
    
  2. Store these API clients fields:

    • User: player’s credentials.
    • SessionBrowser: allow another player to query the ongoing P2P session.
    • Lobby: allow the player to establish WebSocket connection and it initiates the early stage of P2P connection. LobbyApi & WebSocket are required to form the Lobby.
    AccelByte.Api.User user = apiClient.GetApi<User, UserApi>();
    AccelByte.Api.SessionBrowser sessionBrowser = apiClient.GetApi<SessionBrowser, SessionBrowserApi>();
    AccelByte.Api.Lobby lobby = apiClient.GetApi<Lobby, LobbyApi>();
    

# Sequence

# Library Initialization

Call this command once only:

Unity.WebRTC.WebRTC.Initialize();

NOTE

Be careful with the nativeLoggingSeverity parameter. Using Initialize() can cause it to print excessive logs which can affect system performance.

# Log the Player In

The User class has various types of login, choose one and ensure the callback return is not error.

user.LoginWithUsername(email, password, result =>
{
    Debug.Log("Is login error? " + result.IsError);
    if (!result.IsError)
    {
        //Proceed to the next step
    }
});

# Lobby Connection

Call the Lobby function to establish a WebSocket connection to the Lobby service. Don’t forget to attach the listener to recognize the connection state.

lobby.Connected += () => Debug.Log("Lobby is connected"); ;
lobby.Connect();

# Create Transport Manager

After the player has connected to the Lobby or WebSocket, select a game object and ensure it won’t be destroyed. Add the AccelByteNetworkTransportManager component to that object.

var transportManager = gameObject.AddComponent<AccelByteNetworkTransportManager>();
transportManager.Initialize(apiClient);

If you have Unity Netcode NetworkManager in your scene’s singleton, you can pass the component’s reference to the NetworkTransport selection.

p2p-unity

# Setup the Requirement

This section mainly uses the transportManager function.

# As Host

Setup the specification of the session that will be hosted using this function.

transportManager.SetSessionBrowserCreationRequest(...)

This function accepts three parameters:

public void SetSessionBrowserCreationRequest(SessionBrowserGameSetting gameSessionSetting, string username, string game_version)

An example of SessionBrowserGameSetting:

var setting = new SessionBrowserGameSetting();
setting.mode = CURRENT_GAME_MODE;
setting.map_name = CURRENT_MAP_NAME;
setting.num_bot = 0;
setting.max_player = 4;
setting.max_internal_player = 2;
setting.current_player = 1;
setting.current_internal_player = 1;
setting.allow_join_in_progress = true;

# As Client

# Obtain the UserID

The most important information you should have is the UserID of the host. You can get this by querying the available session. Use the sessionBrowser API that was created in the ApiClient section. This API has GetGameSessions function and accepts one query parameter (SessionBrowserQuerySessionFilter). Example of the filter:

var queryFilter = new SessionBrowserQuerySessionFilter
{
sessionType = SessionType.p2p,
gameMode = CURRENT_GAME_MODE
};

Example of function usage:

GetGameSessions(queryFilter, result =>
{
    if (    result.IsError ||
result.Value == null ||
result.Value.sessions == null ||
result.Value.sessions.Length == 0)
    {
     Debug.Log("Can not found any session");
     return;
    }

    foreach (var session in result.Value.sessions)
    {
     Debug.Log(session.user_id);    
    }
});
# Join the Session

Once you have the userID, you can join the session that is hosted by that player.

transportManager.SetTargetHostUserId(userID);

# AccelByteNetworkTransportManager Ready

Once you have connected to a session, the Unity.Netcode.NetworkManager will automatically call either StartHost() or StartClient(). If you want to customize the multiplayer RPC you can use the data directly without NetworkManager, as follows:

# Poll Event

Add the instruction to the transportManager to periodically iterate through the transportManager.PollEvent(..) function. For example:

do
{
networkEvent = transportManager.PollEvent(out ulong clientId, out ArraySegment<byte> payload, out float receiveTime);
HandleRawTransportPoll(networkEvent, clientId, payload, receiveTime);
// Only do another iteration if: there are no more messages AND (there is no limit to max events or we have processed less than the maximum)
} while (IsListening && networkEvent != NetworkEvent.Nothing);

Include each type of networkEvent and process the payload in a similar way to the HandleRawTransportPoll function.