receiving OSC (network) data through unityOSC

Hi - I’m having a little trouble implementing OSC data in unity - I’m using unityOSC

to receive the data. If I manually transmit data through OSC via a script in Unity, everything works fine, but what I’m trying to do is get a third party application (written in openFrameworks) to transmit OSC data and have Unity receive it. I know that the third party app transmits the data properly (I can receive it via OSCulator. But Unity does not recognize any signals as being transmitted, probably because I am not setting up the client /server properly.

The client is set up in openFrameworks to broadcast OSC data on port 8338 (of localhost). How do I change my code in Unity below to receive that data? Note that the code looks long, but really the only things that I think need adjustment are the init function of OSCFaceshift.cs, or the init function of OSCHandler.cs:

OSCFaceshift.cs - (The code I wrote)

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityOSC;

public class OSCFaceshift : MonoBehaviour {
    private Dictionary<string, ServerLog> servers;

    // Script initialization
    void Start() {  
        OSCHandler.Instance.Init(); 
        servers = new Dictionary<string, ServerLog>();
    }

    void Update() {

        OSCHandler.Instance.UpdateLogs();
        servers = OSCHandler.Instance.Servers;

        foreach(KeyValuePair<string, ServerLog> item in servers)
        {
            // If we have received at least one packet,
            // show the last received from the log in the Debug console
            if(item.Value.log.Count > 0) 
            {
                int lastPacketIndex = item.Value.packets.Count - 1;

                UnityEngine.Debug.Log(String.Format("SERVER: {0} ADDRESS: {1} VALUE 0: {2}", 
                item.Key, // Server name
                item.Value.packets[lastPacketIndex].Address, // OSC address
                item.Value.packets[lastPacketIndex].Data[0].ToString())); //First data value
            }
        }

        if (Input.GetButtonDown("Fire1") ){
            OSCHandler.Instance.SendMessageToClient("FaceClient", "test/alive", "testing");
        }

    }
}

OSC Handler.cs - //The code I downloaded to try and bring OSC into Unity

//
//    UnityOSC - Open Sound Control interface for the Unity3d game engine
//
//    Copyright (c) 2011 Jorge Garcia <info@jorgegarciamartin.com>
//
//    This library is free software; you can redistribute it and/or
//    modify it under the terms of the GNU Lesser General Public
//    License as published by the Free Software Foundation; either
//    version 2.1 of the License, or (at your option) any later version.
//
//    This library is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
//    Lesser General Public License for more details.
//
//    You should have received a copy of the GNU Lesser General Public
//    License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
/// Inspired by http://www.unifycommunity.com/wiki/index.php?title=AManagerClass

using System;
using System.Net;
using System.Collections.Generic;

using UnityEngine;
using UnityOSC;

/// <summary>
/// Models a log of a server composed by an OSCServer, a List of OSCPacket and a List of
/// strings that represent the current messages in the log.
/// </summary>
public struct ServerLog
{
    public OSCServer server;
    public List<OSCPacket> packets;
    public List<string> log;
}

/// <summary>
/// Models a log of a client composed by an OSCClient, a List of OSCMessage and a List of
/// strings that represent the current messages in the log.
/// </summary>
public struct ClientLog
{
    public OSCClient client;
    public List<OSCMessage> messages;
    public List<string> log;
}

/// <summary>
/// Handles all the OSC servers and clients of the current Unity game/application.
/// Tracks incoming and outgoing messages.
/// </summary>
public class OSCHandler : MonoBehaviour
{
    #region Singleton Constructors
    static OSCHandler()
    {
    }

    OSCHandler()
    {
    }

    public static OSCHandler Instance 
    {
        get 
        {
            if (_instance == null) 
            {
                _instance = new GameObject ("OSCHandler").AddComponent<OSCHandler>();
            }

            return _instance;
        }
    }
    #endregion

    #region Member Variables
    private static OSCHandler _instance = null;
    private Dictionary<string, ClientLog> _clients = new Dictionary<string, ClientLog>();
    private Dictionary<string, ServerLog> _servers = new Dictionary<string, ServerLog>();

    private const int _loglength = 25;
    #endregion

    /// <summary>
    /// Initializes the OSC Handler.
    /// Here you can create the OSC servers and clientes.
    /// </summary>
    public void Init()
    {
        //Initialize OSC clients (transmitters)
        CreateClient("FaceClient", IPAddress.Parse("127.0.0.1"), 33433);

        //Initialize OSC servers (listeners)
        //Example:

        CreateServer("FaceServer", 8338); //MH - do we need to create a server? The server is Unity itself...   
    }

    #region Properties
    public Dictionary<string, ClientLog> Clients
    {
        get
        {
            return _clients;
        }
    }

    public Dictionary<string, ServerLog> Servers
    {
        get
        {
            return _servers;
        }
    }
    #endregion

    #region Methods

    /// <summary>
    /// Ensure that the instance is destroyed when the game is stopped in the Unity editor
    /// Close all the OSC clients and servers
    /// </summary>
    void OnApplicationQuit() 
    {
        foreach(KeyValuePair<string,ClientLog> pair in _clients)
        {
            pair.Value.client.Close();
        }

        foreach(KeyValuePair<string,ServerLog> pair in _servers)
        {
            pair.Value.server.Close();
        }

        _instance = null;
    }

    /// <summary>
    /// Creates an OSC Client (sends OSC messages) given an outgoing port and address.
    /// </summary>
    /// <param name="clientId">
    /// A <see cref="System.String"/>
    /// </param>
    /// <param name="destination">
    /// A <see cref="IPAddress"/>
    /// </param>
    /// <param name="port">
    /// A <see cref="System.Int32"/>
    /// </param>
    public void CreateClient(string clientId, IPAddress destination, int port)
    {
        ClientLog clientitem = new ClientLog();
        clientitem.client = new OSCClient(destination, port);
        clientitem.log = new List<string>();
        clientitem.messages = new List<OSCMessage>();

        _clients.Add(clientId, clientitem);

        // Send test message
        string testaddress = "/test/alive/";
        OSCMessage message = new OSCMessage(testaddress, destination.ToString());
        message.Append(port); message.Append("OK");

        _clients[clientId].log.Add(String.Concat(DateTime.UtcNow.ToString(),".",
                                                 FormatMilliseconds(DateTime.Now.Millisecond), " : ",
                                                 testaddress," ", DataToString(message.Data)));
        _clients[clientId].messages.Add(message);

        _clients[clientId].client.Send(message);
    }

    /// <summary>
    /// Creates an OSC Server (listens to upcoming OSC messages) given an incoming port.
    /// </summary>
    /// <param name="serverId">
    /// A <see cref="System.String"/>
    /// </param>
    /// <param name="port">
    /// A <see cref="System.Int32"/>
    /// </param>
    public void CreateServer(string serverId, int port)
    {
        //Debug.Log("Create Server");
        ServerLog serveritem = new ServerLog();
        serveritem.server = new OSCServer(port);
        serveritem.log = new List<string>();
        serveritem.packets = new List<OSCPacket>();

        _servers.Add(serverId, serveritem);
    }

    /// <summary>
    /// Sends an OSC message to a specified client, given its clientId (defined at the OSC client construction),
    /// OSC address and a single value. Also updates the client log.
    /// </summary>
    /// <param name="clientId">
    /// A <see cref="System.String"/>
    /// </param>
    /// <param name="address">
    /// A <see cref="System.String"/>
    /// </param>
    /// <param name="value">
    /// A <see cref="T"/>
    /// </param>
    public void SendMessageToClient<T>(string clientId, string address, T value)
    {
        //Debug.Log("SMTC");
        List<object> temp = new List<object>();
        temp.Add(value);

        SendMessageToClient(clientId, address, temp);
    }

    /// <summary>
    /// Sends an OSC message to a specified client, given its clientId (defined at the OSC client construction),
    /// OSC address and a list of values. Also updates the client log.
    /// </summary>
    /// <param name="clientId">
    /// A <see cref="System.String"/>
    /// </param>
    /// <param name="address">
    /// A <see cref="System.String"/>
    /// </param>
    /// <param name="values">
    /// A <see cref="List<T>"/>
    /// </param>
    public void SendMessageToClient<T>(string clientId, string address, List<T> values)
    {   

        if(_clients.ContainsKey(clientId))
        {
            OSCMessage message = new OSCMessage(address);

            foreach(T msgvalue in values)
            {
                message.Append(msgvalue);
                Debug.Log(msgvalue);
            }

            if(_clients[clientId].log.Count < _loglength)
            {
                _clients[clientId].log.Add(String.Concat(DateTime.UtcNow.ToString(),".",
                                                         FormatMilliseconds(DateTime.Now.Millisecond),
                                                         " : ", address, " ", DataToString(message.Data)));
                _clients[clientId].messages.Add(message);
            }
            else
            {
                _clients[clientId].log.RemoveAt(0);
                _clients[clientId].messages.RemoveAt(0);

                _clients[clientId].log.Add(String.Concat(DateTime.UtcNow.ToString(),".",
                                                         FormatMilliseconds(DateTime.Now.Millisecond),
                                                         " : ", address, " ", DataToString(message.Data)));
                _clients[clientId].messages.Add(message);
            }

            _clients[clientId].client.Send(message);
        }
        else
        {
            Debug.LogError(string.Format("Can't send OSC messages to {0}. Client doesn't exist.", clientId));
        }
    }

    /// <summary>
    /// Updates clients and servers logs.
    /// </summary>
    public void UpdateLogs()
    {
        foreach(KeyValuePair<string,ServerLog> pair in _servers)
        {
            if(_servers[pair.Key].server.LastReceivedPacket != null)
            {
                //Initialization for the first packet received
                if(_servers[pair.Key].log.Count == 0)
                {   
                    _servers[pair.Key].packets.Add(_servers[pair.Key].server.LastReceivedPacket);

                    _servers[pair.Key].log.Add(String.Concat(DateTime.UtcNow.ToString(), ".",
                                                             FormatMilliseconds(DateTime.Now.Millisecond)," : ",
                                                             _servers[pair.Key].server.LastReceivedPacket.Address," ",
                                                             DataToString(_servers[pair.Key].server.LastReceivedPacket.Data)));
                    break;
                }

                if(_servers[pair.Key].server.LastReceivedPacket.TimeStamp
                   != _servers[pair.Key].packets[_servers[pair.Key].packets.Count - 1].TimeStamp)
                {   
                    if(_servers[pair.Key].log.Count > _loglength - 1)
                    {
                        _servers[pair.Key].log.RemoveAt(0);
                        _servers[pair.Key].packets.RemoveAt(0);
                    }

                    _servers[pair.Key].packets.Add(_servers[pair.Key].server.LastReceivedPacket);

                    _servers[pair.Key].log.Add(String.Concat(DateTime.UtcNow.ToString(), ".",
                                                             FormatMilliseconds(DateTime.Now.Millisecond)," : ",
                                                             _servers[pair.Key].server.LastReceivedPacket.Address," ",
                                                             DataToString(_servers[pair.Key].server.LastReceivedPacket.Data)));
                }
            }
        }
    }

    /// <summary>
    /// Converts a collection of object values to a concatenated string.
    /// </summary>
    /// <param name="data">
    /// A <see cref="List<System.Object>"/>
    /// </param>
    /// <returns>
    /// A <see cref="System.String"/>
    /// </returns>
    private string DataToString(List<object> data)
    {
        string buffer = "";

        for(int i = 0; i < data.Count; i++)
        {
            buffer += data*.ToString() + " ";*

}

buffer += "
";

return buffer;
}

///


/// Formats a milliseconds number to a 000 format. E.g. given 50, it outputs 050. Given 5, it outputs 005
///

///
/// A
///
///
/// A
///
private string FormatMilliseconds(int milliseconds)
{
if(milliseconds < 100)
{
if(milliseconds < 10)
return String.Concat(“00”,milliseconds.ToString());

return String.Concat(“0”,milliseconds.ToString());
}

return milliseconds.ToString();
}

#endregion
}

Hi, could you answer be this, in the readme is UnityOSC on GitHub?

Known issues

  • Since bundle information is not implemented fully, receiving messages in Unity fails while using bundles (e.g. when sending OSC from OpenFrameworks with ofxOSC)

Sorry I can’t comment on your code…

I fixed the issue regarding openframeworks #bundle management by integrating a VVVV addon in Unity. Code is available here: GitHub - frankiezafe/VVVVUnityOSC: Main repo is here:
README.md file contains a short explanation on how to integrate the code.