Skip to main content
Version: 1.x

Understanding User Data

Every peer (player or user connected to an ODIN room) has its own user data. User data within ODIN is always defined like this:

public byte[] UserData { get; set; }

As you can see, it's just an array of bytes. It's completely up to you how you use this. For example, in simpler games like casual games, board games, or other forms of multiplayer games that don't need advanced features like movement prediction, you don't need to use complex multiplayer frameworks like Mirror Networking or Unity MLAPI to build your game. ODIN's user data is typically enough, as you can link your custom scripts to the

OnPeerUserDataChanged

callback, which is called whenever user data changes for a connected peer.

If you plan or already use one of those more complex frameworks, you need to sync ODIN with those tools, as in this case, your players connect to two different servers: the (dedicated) server for the game and ODIN's backend servers for voice. Don't worry, it's simpler than it seems, as the ODIN SDK does all the heavy lifting for you. In your multiplayer game, players might be in different teams, and only those teams should be in the same ODIN room. To sync up this information between ODIN and your game, you can use UserData.

In our examples, we use a simple class that exposes a simple structure and serializes that to a JSON string that is set as the peer's user data. Then, "on the other side," this string is serialized back into a class instance.

You'll find this class in the samples folder of the Unity SDK and it looks like this:

CustomUserDataJsonFormat implementation
using OdinNative.Odin;
using System;
using System.Text;
using UnityEngine;

namespace OdinNative.Unity.Samples
{
[Serializable]
class CustomUserDataJsonFormat : IUserData
{
public string name;
public string seed;
public string status;
public int muted;
public string user;
public string renderer;
public string platform;
public string revision;
public string version;
public string buildno;

public CustomUserDataJsonFormat() : this("Unity Player", "online") { }
public CustomUserDataJsonFormat(string name, string status)
{
this.name = name;
this.seed = SystemInfo.deviceUniqueIdentifier;
this.status = status;
this.muted = 0;
this.user = string.Format("{0}.{1}", Application.companyName, Application.productName);
this.renderer = Application.unityVersion;
this.platform = string.Format("{0}/{1}", Application.platform, Application.unityVersion);
this.revision = "0";
this.version = Application.version;
this.buildno = Application.buildGUID;
}

public UserData ToUserData()
{
return new UserData(this.ToJson());
}

public static CustomUserDataJsonFormat FromUserData(UserData userData)
{
return JsonUtility.FromJson<CustomUserDataJsonFormat>(userData.ToString());
}

public static bool FromUserData(UserData userData, out CustomUserDataJsonFormat customUserData)
{
try
{
customUserData = JsonUtility.FromJson<CustomUserDataJsonFormat>(userData.ToString());
return true;
}
catch (Exception e)
{
Debug.LogException(e);
customUserData = null;
return false;
}
}

internal string GetAvatarUrl()
{
return string.Format("https://avatars.dicebear.com/api/bottts/{0}.svg?textureChance=0", this.seed);
}

public string ToJson()
{
return JsonUtility.ToJson(this);
}

public override string ToString()
{
return this.ToJson();
}

public byte[] ToBytes()
{
return Encoding.UTF8.GetBytes(this.ToString());
}
}
}

If you like this way of handling user data, copy & paste this code into your own Unity project, rename it to whatever pleases you (and change the namespace). Then, just use it to set User Data when joining a room:

Using our CustomUserDataJsonFormat
    // Generate a JSON User Data object with the player's netId and name in the network
CustomUserDataJsonFormat userData = new CustomUserDataJsonFormat(name, "online");
userData.seed = netId.ToString();

// Join ODIN Room ShooterSample and send user data
OdinHandler.Instance.JoinRoom("ShooterSample", userData.ToUserData());

Customize the structure to make sense for your own game.

We have a comprehensive guide on how to leverage UserData to sync up ODIN with a multiplayer game created with Mirror Networking.