Skip to main content
Last updated on November 10, 2025

Set Up Matchmaking Using Unity SDK

To implement matchmaking into your game, follow these steps:

Start matchmaking

  • Make sure you have set up IAM Clients with proper permissions to be used for the game. Follow the steps in the Manage access control for application article.

  • Enable P2P related settings. You can use exact configuration as shown in the image below. We recommend using this configuration. For turn manager server URL, change it to your environment-specific URL. Turn server host, port, username, secret and password are optional. These settings are only used when using static auth key for the TURN server. In this example, we use dynamic auth key and tbe mentioned settings are left empty.

AccelByte Configuration screen

Initialize AccelByte network transport and listen to network event

Before initializing the network transport of the game client, you need to log in to AGS and connect to the lobby first. The following snippet code shows how to connect and initialize network transport.

var apiClient = AccelByteSDK.GetClientRegistry().GetApi();
var user = apiClient.GetUser();
var lobby = apiClient.GetLobby();

// instantiate transport manager
AccelByteNetworkTransportManager TransportManager = gameObject.AddComponent<AccelByteNetworkTransportManager>();

// Initialize transport manager after the client is logged in and lobby is connected
lobby.Connected += () =>
{
TransportManager.Initialize(apiClient);
};

// Login and connect lobby
user.LoginWithEmailV4("email", "password", result =>
{
if (result.IsError)
{
// Handle login error
Debug.Log($"Login Failed: {result.Error.error_description}");
return;
}

// Handle login success
lobby.Connect();
});

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

Network Transport step

Start matchmaking, join game session, and initiate P2P connection

Below is snippet code for start matchmaking

var apiClient = AccelByteSDK.GetClientRegistry().GetApi();
var lobby = apiClient.GetLobby();
var session = apiClient.GetSession();
var matchmaking = apiClient.GetMatchmakingV2();

AccelByteNetworkTransportManager transportManager = gameObject.AddComponent<AccelByteNetworkTransportManager>();

// This notification will be received after the party leader starts the matchmaking
lobby.MatchmakingV2MatchmakingStarted += result =>
{
if (result.IsError)
{
// Handle MatchmakingV2MatchmakingStarted error
Debug.Log($"Error MatchmakingV2MatchmakingStarted, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
return;
}

// Handle MatchmakingV2MatchmakingStarted success
Debug.Log($"Matchmaking started: {result.Value.ticketId}");
};

// This notification will be received after the match is found
lobby.MatchmakingV2MatchFound += result =>
{
if (result.IsError)
{
// Handle MatchmakingV2MatchFound error
Debug.Log($"Error MatchmakingV2MatchFound, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
return;
}

// Handle MatchmakingV2MatchFound success
Debug.Log($"Match found: {result.Value.id} {result.Value.matchPool}");
};

// This notification will be received after match is found and game client can accept it
lobby.SessionV2InvitedUserToGameSession += result =>
{
if (result.IsError)
{
// Handle SessionV2InvitedUserToGameSession error
Debug.Log($"Error SessionV2InvitedUserToGameSession, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
return;
}

// Handle SessionV2InvitedUserToGameSession success
Debug.Log($"Invited to a game session {result.Value.sessionId}");

session.JoinGameSession(result.Value.sessionId, joinGameSessionResult =>
{
if (joinGameSessionResult.IsError)
{
// Handle JoinGameSession error
Debug.Log($"Error joinGameSessionResult, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
return;
}

// Handle JoinGameSession success
Debug.Log($"Successfully joined game session {joinGameSessionResult.Value.id}");

// Start as a host if the current user is the leader of game session (it means that this user is the first one to join the game)
string gameSessionLeaderId = joinGameSessionResult.Value.leaderId;
if (gameSessionLeaderId == "current-user-member-id")
{
transportManager.StartServer();
}
else
{
transportManager.SetTargetHostUserId(gameSessionLeaderId);
transportManager.StartClient();
}
});
};

// Start matchmaking
var matchpoolName = "matchpool-name";
var optionalParams = new MatchmakingV2CreateTicketRequestOptionalParams();
matchmaking.CreateMatchmakingTicket(matchpoolName, optionalParams, result =>
{
if (result.IsError)
{
// Handle CreateMatchmakingTicket error
Debug.Log($"Error CreateMatchmakingTicket, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
return;
}

// Handle CreateMatchmakingTicket success
Debug.Log($"Successfully created matchmaking ticket {result.Value.matchTicketId}");
});

Send data to peer without Unity Netcode

To send data to peer, use this method in your game client:

byte[] data = System.Text.Encoding.ASCII.GetBytes("sample data");
ulong peerId = 0;
transportManager.Send(peerId, new ArraySegment<byte>(data), NetworkDelivery.Reliable);

Receive data from peer without Unity Netcode

To receive data from peer, you can set the game client to listen to the previously registered callback for OnTransportEvent, or, alternatively, poll the events using this method:

var networkEvent = transportManager.PollEvent(out ulong clientId, out ArraySegment<byte> payload, out float receiveTime);