Use Relay with Netcode for GameObjects

Relay works seamlessly with Netcode for GameObjects, which is a Unity package that provides networking capabilities to GameObject and MonoBehaviour workflows.

This tutorial shows how to use Relay with Netcode for GameObjects and the Unity Transport Package (UTP).

Installation and configuration

  1. In the Unity Editor's Package Manager, select Unity Registry.
  2. Search for the following package:
    • For Unity 2022 LTS and later: com.unity.services.multiplayer
    • For earlier versions of Unity: com.unity.services.relay

    Note: For most users, the unified Multiplayer Services package replaces the Relay standalone package, which is deprecated in Unity 6. Consider migrating to the unified package to facilitate a smooth transition. Visit the migration guide for a step-by-step transition process.

  3. Select the package, then Install. Refer to Package Manager.
  4. Repeat for com.unity.netcode.gameobjects.

You must first configure your Unity project for Unity before using Relay with Netcode for GameObjects. Refer to Get started with Relay to learn how to link your project in the project settings.

Set up the NetworkManager

After installing the packages, you can now set up the NetworkManager:

  1. Add a new GameObject to your scene.
  2. Add the NetworkManager MonoBehaviour.
  3. In the MonoBehaviour Properties, select the UnityTransport transport. After selecting UnityTransport, you’ll see a MonoBehaviour called Unity Transport (script) at the bottom of the components list.
  4. Set the Protocol Type of the new component to Relay Unity Transport.

Host player

The StartHostWithRelay function shows how to create a Relay allocation, and request a join code. This function requires the maximum number of connections the allocation is expecting and the host player connection type.

The connection type must be one of the following options:

  • udp
  • dtls
  • wss

Refer to DTLS to learn more about DTLS encryption, and to Web Platform Support to learn about using wss.

This code should be adapted to your needs to use a different authentication mechanism, a different error handling, or to use a different connection type. Similarly, you can call StartServer instead of StartHost to start a server instead of a host.

Using the Relay standalone SDK (com.unity.services.relay)

public async Task<string> StartHostWithRelay(int maxConnections, string connectionType)
{
    await UnityServices.InitializeAsync();
    if (!AuthenticationService.Instance.IsSignedIn)
    {
        await AuthenticationService.Instance.SignInAnonymouslyAsync();
    }
    var allocation = await RelayService.Instance.CreateAllocationAsync(maxConnections);
    NetworkManager.Singleton.GetComponent<UnityTransport>().SetRelayServerData(new RelayServerData(allocation, connectionType));
    var joinCode = await RelayService.Instance.GetJoinCodeAsync(allocation.AllocationId);
    return NetworkManager.Singleton.StartHost() ? joinCode : null;
}

Note: If this code succeeds in calling the NetworkManager.Singleton.StartHost(), it returns the join code retrieved from the Relay allocation.

Using the Multiplayer Services SDK (com.unity.services.multiplayer)

Note: The Multiplayer Services Package introduces the concept of session. Check out Build a session with Netcode for GameObjects to learn how to use it.

public async Task<string> StartHostWithRelay(int maxConnections, string connectionType)
{
    await UnityServices.InitializeAsync();
    if (!AuthenticationService.Instance.IsSignedIn)
    {
        await AuthenticationService.Instance.SignInAnonymouslyAsync();
    }
    var allocation = await RelayService.Instance.CreateAllocationAsync(maxConnections);
    NetworkManager.Singleton.GetComponent<UnityTransport>().SetRelayServerData(AllocationUtils.ToRelayServerData(allocation, connectionType));
    var joinCode = await RelayService.Instance.GetJoinCodeAsync(allocation.AllocationId);
    return NetworkManager.Singleton.StartHost() ? joinCode : null;
}

Note: If this code succeeds in calling the NetworkManager.Singleton.StartHost(), it returns the join code retrieved from the Relay allocation.

Joining player

When your game client functions as a joining player, the relay join code, retrieved in the previous step when the host created the allocation, must be passed to find the allocation. The following code samples show how to join an allocation with a join code and configure the connection type.

The connection type must be one of the following options:

  • udp
  • dtls
  • wss

Refer to DTLS to learn more about DTLS encryption, and to Web Platform Support to learn about using wss.

Using the Relay standalone SDK (com.unity.services.relay)

public async Task<bool> StartClientWithRelay(string joinCode, string connectionType)
{
    await UnityServices.InitializeAsync();
    if (!AuthenticationService.Instance.IsSignedIn)
    {
        await AuthenticationService.Instance.SignInAnonymouslyAsync();
    }

    var allocation = await RelayService.Instance.JoinAllocationAsync(joinCode);
    NetworkManager.Singleton.GetComponent<UnityTransport>().SetRelayServerData(new RelayServerData(allocation, connectionType));
    return !string.IsNullOrEmpty(joinCode) && NetworkManager.Singleton.StartClient();
}

Using the Multiplayer Services SDK (com.unity.services.multiplayer)

Note: The Multiplayer Services Package introduces the concept of session. Check out Build a session with Netcode for GameObjects to learn how to use it.

public async Task<bool> StartClientWithRelay(string joinCode, string connectionType)
{
    await UnityServices.InitializeAsync();
    if (!AuthenticationService.Instance.IsSignedIn)
    {
        await AuthenticationService.Instance.SignInAnonymouslyAsync();
    }

    var allocation = await RelayService.Instance.JoinAllocationAsync(joinCode: joinCode);
    NetworkManager.Singleton.GetComponent<UnityTransport>().SetRelayServerData(AllocationUtils.ToRelayServerData(allocation, connectionType));
    return !string.IsNullOrEmpty(joinCode) && NetworkManager.Singleton.StartClient();
}

Note about Unity Web platform support

To use Relay with Netcode for GameObjects in Unity Web platform supported game, upgrade the Unity Transport Package to 2.0.0 or later and configure the Unity transport component to use Web Sockets.

Using the above code snippets, pass wss as connectionType and use the following to SetRelayServerData:

Using the Relay standalone SDK (com.unity.services.relay)

NetworkManager.Singleton.GetComponent<UnityTransport>().SetRelayServerData(new RelayServerData(allocation, connectionType));
NetworkManager.Singleton.GetComponent<UnityTransport>().UseWebSockets = true;

Using the Multiplayer Services SDK (com.unity.services.multiplayer)

NetworkManager.Singleton.GetComponent<UnityTransport>().SetRelayServerData(AllocationUtils.ToRelayServerData(allocation, connectionType));
NetworkManager.Singleton.GetComponent<UnityTransport>().UseWebSockets = true;