Immerse

Custom messages

The multi-user capability of the Immerse Virtual Enterprise Platform works by sending different types of messages between clients within a session. Each message type has a set of behaviours and is handled in different ways when received by a user. It is possible for an Immerse SDK developer to create their own message types for use in a project.

📘

Immerse SDK Class Library

More detail available in ImmerseSDK.Multiplayer.Messaging namespace

Creating a New Message Type

Register a new Custom Message type:

The project's list of custom messages can be found in the Unity Project Settings panel under 'Immerse > Custom Messages'. This page contains an array where message descriptors can be defined.

Increase the size of the array to add an entry, then fill out the fields for your custom message.

NameThe name of the message
DescriptionA description of what the message is for (optional)
Message TypeA unique ID for this message (0 - 999 is reserved for SDK system messages)
ProfileWho can send this message?
- Space Owner: only the person who created the session can send this message
- Participant: anyone in the session can send this message
Is Persisted in SessionShould this message be remembered by the server and sent to new and returning users?
Broadcast Back to SelfShould the server send this message back to the sender?

This message list will be included in the build as part of the meta file and processed when uploaded to the Immerse Platform.

Once the message has been registered, it can be used in a scene.

Sending A Custom Message

To send a message:

  1. Wait until your client is connected to the multi-user session
  2. Get reference to the Custom Message Manager
  3. Call SendCustomMessage
using ImmerseSDK;
using ImmerseSDK.Multiplayer.Messaging;
using UnityEngine;

public class SendMessageExample : MonoBehaviour
{
    public void SendCustomMessage()
    {        
        // Construct our payload of data (array of bytes)
        var payload = new byte[] {2, 4, 1};
        
        // Get the message manager and send a message
        const ushort myMessageType = 1001;
        var customMessageManager = SingletonManager.Get<CustomMessageManager>();
        customMessageManager.SendCustomMessage(myMessageType, payload);
    }
}

Receiving a Custom Message

In order to receive a message, we have to start listening for it. To do this, a handler must be registered with the Custom Message Manager.

📘

If the message handler has not been registered at the time of the message being sent, the message will be lost. For this reason, create your application to start listening for the message, as soon as the Custom Message Manager is ready.

To register a message handler:

  1. Wait for the Custom Message Manager to be ready
  2. Register the message handler
  3. Process your payload
using System.Collections;
using ImmerseSDK;
using ImmerseSDK.Multiplayer.Messaging;
using UnityEngine;

public class ReceiveMessageExample : MonoBehaviour
{
    private IEnumerator Start()
    {
        // Wait for the Custom Message Manager to be ready
        yield return this.WaitFor<CustomMessageManager>();

        // Register message handler
        const ushort messageType = 1001;
        var messageManager = SingletonManager.Get<CustomMessageManager>();
        messageManager.RegisterCustomMessageCallback(messageType, HandleMessage);
    }

    private bool HandleMessage(GhostMessage message)
    {
        // EXAMPLE: Print each byte in our payload
        foreach (var b in message.Payload)
        {
            Debug.Log(b);
        }
        return true;
    }
}

Serialization

To send complex data through a message, it is possible to serialize many data types into a byte array which can then be sent. There are many different ways to do this and different methods should be considered for each case. It is often a balance between convenience and performance.

Using JSON

One common method of serialization is to use JSON, which is a slower but more convenient method for serializing data. Unity provides tools for serializing and deserializing for this format. More information can be found in the Unity documentation for JsonUtility

Once the data is in JSON format, the string just needs to be converted into a byte array, which can be done easily.

Example: Serializing an object using JSON

using System;
using System.Text;
using ImmerseSDK;
using ImmerseSDK.Multiplayer.Messaging;
using UnityEngine;

public class SendingJsonExample : MonoBehaviour
{
    [Serializable]
    public class ExampleData
    {
        public string TextValue;
        public int Number;

        public override string ToString() => $"{TextValue} - {Number}";
    }
    
    public void SendMessage(ExampleData dataToSend)
    {
        // Serialize our data to JSON
        var json = JsonUtility.ToJson(dataToSend);
        
        // Encode the JSON to a byte array using UTF8
        var payload = Encoding.UTF8.GetBytes(json);

        // Send our message
        const ushort messageType = 1001;
        var messageManager = SingletonManager.Get<CustomMessageManager>();
        messageManager.SendCustomMessage(messageType, payload);
    }
}
using System;
using System.Collections;
using System.Text;
using ImmerseSDK;
using ImmerseSDK.Multiplayer.Messaging;
using UnityEngine;

public class ReceivingJsonExample : MonoBehaviour
{
    private IEnumerator Start()
    {
        // Wait for the Custom Message Manager to be ready
        yield return this.WaitFor<CustomMessageManager>();
        
        // Register message handler
        const ushort messageType = 1001;
        var messageManager = SingletonManager.Get<CustomMessageManager>();
        messageManager.RegisterCustomMessageCallback(messageType, HandleMessage);
    }

    private bool HandleMessage(GhostMessage message)
    {
        // Get the JSON from the byte array we just received
        var json = Encoding.UTF8.GetString(message.Payload);
        
        // Deserialize the JSON
        var data = JsonUtility.FromJson<SendingJsonExample.ExampleData>(json);
        
        // Use our data
        Debug.Log(data);
        return true;
    }
}

Using Buffer.BlockCopy to Populate Byte Arrays

If speed is a necessity and it is important to keep payload size small then this method provides a flexible but more complicated way of serializing data:

Example: Serializing an array of floats using Buffer.BlockCopy

using System;
using System.Collections;
using ImmerseSDK;
using ImmerseSDK.Multiplayer.Messaging;
using UnityEngine;

public class SendingArrayExample : MonoBehaviour
{
    [SerializeField] private float[] _data;
    
    public void SendData()
    {
        // Create a byte array big enough to hold all of our data
        var byteCount = _data.Length * sizeof(float);
        var payload = new byte[byteCount];
        
        // Copy our data into the payload byte array
        Buffer.BlockCopy(_data, 0, payload, 0, byteCount);

        // Send our message
        const ushort messageType = 1001;
        var messageManager = SingletonManager.Get<CustomMessageManager>();
        messageManager.SendCustomMessage(messageType, payload);
    }
}
using System;
using System.Collections;
using ImmerseSDK;
using ImmerseSDK.Multiplayer.Messaging;
using UnityEngine;

public class ReceivingArrayExample : MonoBehaviour
{
    private IEnumerator Start()
    {
        // Wait for the Custom Message Manager to be ready
        yield return this.WaitFor<CustomMessageManager>();

        // Register message handler
        const ushort messageType = 1001;
        var messageManager = SingletonManager.Get<CustomMessageManager>();
        messageManager.RegisterCustomMessageCallback(messageType, HandleMessage);
    }

    private bool HandleMessage(GhostMessage message)
    {
        // Create an array big enough to contain all of our data
        var data = new float[message.PayloadLength / sizeof(float)];
        
        // Copy the data from the payload into our array
        Buffer.BlockCopy(message.Payload, 0, data, 0, message.PayloadLength);
        
        // Use our data
        foreach (var value in data)
        {
            Debug.Log(value);
        }
        return true;
    }
}

Unity iconTry out this component in the Examples project

Examples (menu) > Network > Load Custom Message Example

Learn more about the Examples project

Updated 3 months ago


Custom messages


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.