How to send messages between Unity and Max MSP

Although Unity appears to play ball with Pure Data quite nicely, Max Integration is not the most simple of tasks. I found a collection of scripts and objects which do the trick though; read on for a relatively pain-free way I found to get Max and Unity talking using UDP.

Unity to UDP

The first step is to get Unity’s information sent out, whether that’s a simple number, text, or Boolean. I chose to use UDP, as it works in Max with relatively little fuss (more on that later), although it’s likely that an experienced Java user might be able to get data across in that way.

I found Unity user La1n’s forum post on sending UDP messages from Unity, and modified the code to make it fit for my more simple purposes. Without this script, the project wouldn’t have been possible, as I wouldn’t have known where to start, having just started using C#. A typical script from my modified version looks like this:

using UnityEngine;
using System.Collections;

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

public class Zone1DistanceUDP : MonoBehaviour
{
    private static int localPort;

    // prefs
    private string IP;  // define in init
    public int port;  // define in init

    // “connection” things
    IPEndPoint remoteEndPoint;
    UdpClient client;

    // gui
    string strMessage = “”;

    // call it from shell (as program)
    private static void Main()
    {
        Zone1DistanceUDP sendObj = new Zone1DistanceUDP();
        sendObj.init();
    }
    // start from unity3d
    public void Start()
    {
        init();
    }

    // init
    public void init()
    {
        // Define end point , from which the messages are sent.
        print(“UDPSend.init()”);

        // define
        IP = “127.0.0.1”;
        port = 8001;

        // Send
        remoteEndPoint = new IPEndPoint(IPAddress.Parse(IP), port);
        client = new UdpClient();

        // status
        print(“Sending to ” + IP + ” : ” + port);
        print(“Testing: nc -lu ” + IP + ” : ” + port);
        sendString(“jt”);
    }

    // inputFromConsole
    private void inputFromConsole()
    {
        try
        {
            string text;
            do
            {
                text = Console.ReadLine();

                // Send the text to the remote client .
                if (text != “”)
                {
                    // Encode data using the UTF8 encoding to binary format.
                    byte[] data = Encoding.UTF8.GetBytes(text);

                    // Send the text to the remote client.
                    client.Send(data, data.Length, remoteEndPoint);
                }
            } while (text != “”);
        }
        catch (Exception err)
        {
            print(err.ToString());
        }
    }

    // sendData
    private void sendString(string message)
    {
        try
        {
            //if (message != “”)
            //{
            // Encode data using the UTF8 encoding to binary format.
            byte[] data = Encoding.UTF8.GetBytes(message);

            // Send the message to the remote client.
            client.Send(data, data.Length, remoteEndPoint);
            //}
        }
        catch (Exception err)
        {
            print(err.ToString());
        }
    }

    // Update is called once per frame
    void Update()
    {
        //print (Distance.Zone1Distance);
        sendString(Distance.Zone1Distance);
    }
}

This basically boils down to cutting out a load of stuff that wasn’t needed, and then using the sendString() command in Update() or wherever you need something sent. It is quite cumbersome, but having a separate script for each port is needed at this stage. That said, the script works like any other Unity script, so you can have whatever you like going on within Update() or wherever as usual. Another thing to note is that the message has to be a string using this text, so will need quote marks around phrases, or  .tostring() following any numbers. They then go to Max as numbers.

With this happening, I found that the print message that’s commented out above ensured that Unity wasn’t the issue when troubleshooting. You will need to set a UDP port number in the Init section of the script, and the default IP is localhost, so that you can get the messages on the same computer- although there is scope to have sound being processed on another machine using a its IP address.

Receiving Messages in Max

The next stage was to try UDPReceive in Max to get these messages while Unity was running.  However I received nothing, despite the UDP objects in Max talking to each other okay. The next step was to download Adam Siska’s library of Max objects, which has a UDP receive object that works.

You’ll need a loadbang connected to a message setting the ports for the Sadam.udpreceiver, and but after that, hopefully there will be data when running your Unity project!

The only thing is, it’ll likely be a bunch of ASCII numbers- the same you get from typing into the key object. This is where the Lstring object from Peter Elsea comes in, as it converts these numbers back into plain, useable text.

Hopefully from here, you can add in any information or triggers from Unity, and be well on your way to getting a dynamic Max/Unity project on the way! Using Max for Live, you could even use these objects as a bridge into Ableton Live.

Leave a Reply