Data Sharing in Unity

Most of data sharing is done in LightAct GameObject

In the object’s properties on the right, you’ll see 3 properties:

  • Memory Writing Handle is the name of the shared memory handle Unity is writing to. You need to type the exact same text into JSON memory reader node in LightAct’s Devices window.
  • Memory Reading Handle is the name of the shared memory handle Unity is reading from. Please note, you need to type in the exact same text as the one you typed into JSON memory writer node in LightAct’s Devices window.
  • Memory Size is the amount of memory space (in bytes) Unity reserves for itself (for writing). 1024 should be, for most intents and purposes, more than enough.

Receiving Data from LightAct in Unity

As you probably noticed by now (and as we mentioned before), the floating yellow text above the ‘screen plane’ shows text that is sent from LightAct. Also, the red cube is rotating based on a float value coming from LightAct.

In order to explain that we’ll need to go through the C# LightactPlugin script. We’ll go just through the most essential aspects, for all the detailed information please refer to the script itself where we’ve put some additional explanatory comments.

    //values coming from LightAct and then shared with GameObjects
    public static float valRotation;
    public static string valText;

In the beginning of the script around line 15, we declare 2 public variables.

  • valRotation is a float variable determining the rotation of the red cube
  • valText is a string variable determining the content of the yellow text object.
 //Reading from shared memory
        if(BuildMap(m_memoryReadingHandle, m_memorySize))
        {
            Debug.Log("Reading from shared memory (handle name: "+ m_memoryReadingHandle+") succesful");
        }
        else
            Debug.Log("Reading from shared memory (handle name: " + m_memoryReadingHandle + ") failed");

In the Update function, around line 136 we call BuildMap function. It is a function in the native LightAct plugin, which you are free to use & modify (source code is available as part of LightAct4Unity plugin).

That function sends the data from the shared memory back to BuildMapData function in our C# script.

 void BuildMapData(string keys, string values)
    {
        Debug.Log("Incoming Keys: " + keys);
        Debug.Log("Incoming Values: " + values);

        // let's do some string splitting
        String[] keysArray = keys.Split(','); // comma is our delimiter.
        String[] valuesArray = values.Split(',');
        // you can then transform these values into proper formats (ints, floats etc.) and use them elsewhere in your project.

        float v = 0;

        if (valuesArray.Length > 0 && float.TryParse(valuesArray[0], out v))
        {
            valRotation = v;
        }
        if(valuesArray.Length > 1)
        {
            valText = valuesArray[1];
        }

    }

As you can see the data comes as a string of comma-delimited keys and a string of comma-delimited values.

It is up to you then, to parse these 2 comma-delimited strings the way you want and to write the results into the correct variables or push them to other GameObjects in your project.

In our case, we’ve just saved the values to valRotation and valText public variables.

These variables are then read by Text and Red cube GameObjects with their respective scripts.

Sending data from Unity to LightAct

//values to be sent to LightAct
    public static float float2LA=0.0f;
    public static string string2LA="";

Around line 20 we declare 2 public variables: float2LA and string2LA. Both are set every frame by Blue sphere GameObject and its respective script SphereScript.

void Update()
    {
        transform.position = new Vector3(transform.position.x,Mathf.PingPong(Time.time * 2, max - min) + min, transform.position.z);
        LightactPlugin.float2LA = transform.position.y;
        LightactPlugin.string2LA = "Hello from that blue sphere in Unity";
    }

Update function in SphereScript script. It writes the height of the blue sphere to float2LA variable and some arbitrary text to string2LA.

Let’s have a look now how this is then sent to LightAct. For that we have to go back to LightactPlugin script.

if (createMemHandle(m_memoryWritingHandle, m_memorySize))
        {
            Debug.Log("Opened Shared Memory Write Handle");
        }
        else
        {
            Debug.Log("Error in opening Memory write Handle");
        }

First, we open the shared memory handle in the Start function (around line 104).

//Writing to shared memory. You can change the handle name and size in Unity editor
        if (writeSharedMemory("sphereHeight,sphereText", float2LA.ToString("F", CultureInfo.InvariantCulture) + "," + string2LA, m_memoryWritingHandle, m_memorySize))
        {
        }
        else
        {
            Debug.Log("Shared memory Writing failed");
        }

Then, in the Update function, we call writeSharedMemory function where, in the function’s arguments, we simply concatenate all the keys and values into 2 comma-delimited strings together with shared memory handle and shared memory size.

Actions OnDestroy()

void OnDestroy()
    {
        if(closeMemHandle(m_memoryWritingHandle))
        {
            Debug.Log("Closed Shared Memory Write Handle");
        }
        else
        {
            Debug.Log("Error in Closing Memory Write Handle");
        }

        if (closeMemHandle(m_memoryReadingHandle))
        {
            Debug.Log("Closed Shared Memory Read Handle");
        }
        else
        {
            Debug.Log("Error in Closing Memory Read Handle");
        }
        Debug.Log("Destroy");
    }

It is very important, that we close both memory handles (especially the writing one) when we exit the game. Memory Reading Handle (from Unity’s perspective) should be destroyed by LightAct when it exits, but you shouldn’t forget to call closeMemHandle on the Memory Writing Handle (again, from Unity’s perspective).

Texture Sharing in Unity

This article will explain the most important aspects of Unity Sample Project available free-of charge on our website. It works out-of-the-box with Extremely Simple Unity Integration sample LightAct project, that is available in the Intro Window under the Unity tab

Please note, this is not a tutorial on Unity. We will be explaining only the outline of aforementioned sample project. If you are looking for general Unity instructions, please refer to Unity documentation.

If you are having problems with integrating LightAct plugins specifically, you may ask a question on LightAct Answerhub and we will try to help you as much as we can.

Sending a Texture to Spout

When you open Unity project you should see something similar to this (we’ve already highlighted the most important parts for you):

On the left side, you’ve got Hierarchy  tab where all the GameObjects are listed. The most important ones for Texture sharing are Receiver, which is receiving a texture from Spout, and Sender, which, obviously, is sending it. First, we are going to explain the Sender, and then, at the end of this article, the Receiver

Sending Spout from Unity

First, let’s select Sender GameObject in the Hierarchy tab. 

You will see that it is a camera and that it has SpoutRenderTexture.0 set as the Target Texture. This means that whatever this camera sees is rendered not to a display, but to a Texture.

In its properties on the right, you’ll also see the 2 scripts attached to it. SpoutSender takes care of sending Spout from the camera and InvertCamera script takes care that the texture appears correct. 

Please note the Sharing Name property which you have to type into LightAct as well (in Spout Reader node in the Devices window).

Feel free to go through the scripts themselves, which are all saved in the Scripts folder.

Receiving Spout in Unity

Receiving Spout in Unity is even simpler than sending it. You just create a GameObject (mesh of some sort) and apply SpoutReceiver script to it. If you select Receiver GameObject you’ll see this has been already set up for you.

In its properties on the right, you see SpoutReceiver script has been attached to this GameObject. It has just 2 properties. Select sender allows you to either select Any or Other (specify). If you select Any, Spout Receiver is going to choose the first available Spout sender it can find, but if you select Other (specify), you can type in the name of Spout sender. Please note, you should type in the exact name you typed into Spout writer node in the Devices window of LightAct.

In the next article, we will explain how to set up data sharing in Unity for LightAct .

Data Sharing in LightAct for Unity

Setting up data sharing starts in the Devices window, so let’s open the window by pressing F7 or by going to Window and then pressing Devices. Good!

First, we’ll set up receiving data from Unity in LightAct.

Receiving Data from Unity in LightAct

The node in the Devices window we will explore now, is called JSON memory reader 1. If you select it, you will see Handle name says vars2LA.  In the Data section you can also see some data in JSON format. We can’t explain the whole JSON format here, but please do notice that there are 2 pieces of data in our incoming JSON:

  • sphereHeight is a number going up and down and
  • sphereText is a text saying: “Hello from that blue sphere in Unity”

All you need to know at this point is that sphereHeight and sphereText are JSON Keys and the number and the text are JSON Values.

We’ll need to write the keys into a node later on, but before we do that, let’s finish explaining JSON memory reader node.

I’m sure you noticed the Handle name property is not editable. If you want to make it editable, you have to uncheck Listening checkbox. 

Similarly to Spout name, if you change Handle name property of JSON memory reader node, make sure you change the Handle name in the shared memory writer application. In our case, that is Unity, of course.

Let’s leave Handle name as it is (vars2LA) and check the Listening checkbox again.

We’ve done everything we had to in the Devices window, so its time to close it and open Unity2LA layer.

Setting up Shared Memory Listener node in Layer Layouts

Once Unity2LA layer opens, the node we will start with, is called Shared Memory Listener. Please notice that we typed in the JSON keys (sphereHeight and sphereText) we talked about before.

If you select the node, you will see that we selected our JSON memory reader 1 node as the parent. 

Now, to explain briefly what is happening in the rest of the node chain connected to the Shared Memory Listener node:

  • the Value of sphereHeight key goes to String to Float node, which converts it into float format. Then we multiply the value by 10 and use it as the y value of our blue sphere in the Visualizer.
  • the Value of sphereText key goes to String to Texture node, which transforms the text into a texture and then we bring the resulting texture into a Render to Canvas node, which renders it on top of the incoming Spout texture.

Sending data from LightAct to Unity

To explain how to send data from LightAct to Unity let’s go back to the Devices window.

This time, let’s select JSON memory writer node. If you uncheck the Streaming checkbox you should see something similar to above.

Let’s go through the properties very quickly:

  • Handle name is the name of the shared memory handle. You can type in whatever you want (almost) as long as you use the exact same Handle name on Unity side.
  • Reserved bytes is the amount of memory that should be reserved for this package of data. 1024 should much more than enough.
  • In the Data section you can see whatever LightAct is currently writing to shared memory.

Before we close the Devices window, just make sure you check Streaming checkbox back again. Once you’ve done that, close Devices window and open LA2Unity layer.

The node that we will focus on is Shared Memory Sender. As you can see it has 4 inputs:

  • Float is a float value we are sending
  • FName is the JSON key under which we are sending the preceding float value
  • String is a string value we are sending
  • SName is the JSON key under which we are sending preceding string value.

As you can see, every value of whatever type we are sending, has to be followed by a key under which we are sending it.

That’s how we will be able to know under which key we should look under for a particular value on Unity side.

The only thing that we still need to explain is Shared Memory Sender‘s properties. If you select it you will see that as the Parent device, we’ve selected our JSON Memory Writer node in the Devices window.

Texture Sharing in LightAct for Unity

This article will explain the most important aspects of Extremely Simple Unity Integration sample project that is available in the Intro Window under the Unity tab. It works out-of-the-box with Unity Sample Project available free-of charge on our website.

Please note, we won’t be going into every detail of LightAct. If you are a complete LightAct beginner you might want to have a look at the following resources:

Texture Sharing

Every integration in LightAct starts in Devices window. So, without further ado, let’s open it by pressing F7 or by going to Window and then clicking on Devices.

Once the window opens, you’ll see 5 nodes. We can ignore the one describing your computer, which leaves 2 Spout nodes and 2 JSON memory writer nodes. Let’s focus on Spout first.

Sending Spout from LightAct to Unity

For the purpose of this article, let’s say Spout is a place in computer’s memory where applications can write textures to and from where other applications can read them at the same time in a very fast and efficient way. Each Spout stream has to have a ‘name’ so that the application that’s trying to read the texture, knows which Spout name it should look for.

If you select Spout Writer node, you’ll see both of these properties are on the right. However, as you’ll notice, they are not editable. In order to make them editable, uncheck the Streaming checkbox on the node itself.

Now that we’ve made them editable, let’s walk through them:

  • Spout name is the name of Spout stream LightAct is writing to. You will have to type in the exact same name on Unity side.
  • Texture width and height determine the resolution of the texture. This will affect the Texture connections that you can connect to the Spout Sender node in Layer Layouts.

Let’s leave the entries exactly as they are, at the moment, and just hit Apply or deselect node, if you don’t see Apply button.

Make sure you check the Streaming checkbox back again.

Now all that we have to do is determine which texture we want to send to Unity. We do that in LA2Unity layer in the Sequencer.

Setting up Spout Sender in Layer Layouts

Open LA2Unity layer in the Sequencer by double-clicking on it.

In this Layout, you’ll see a Spout Sender node.

If you select it, you will see, in its properties on the right hand side, that it has our Spout Writer node selected as its parent. This means that it is going to send whichever texture (purple connection) is connected to the Texture pin on the node, to that Spout Writer.

Receiving Spout in LightAct

To receive Spout in LightAct the process is quite similar to sending it. Again, it all starts in the Devices window, so let’s open it again.

However, if you select Spout Reader node, you’ll see that it only has Spout name property. Again, in order to be able to receive the texture from Spout this name has to match exactly the name of Spout stream in the application that is sending it. In our case that is Unity, of course.

Make sure that you check Listening checkbox and then close the Devices window. Next, open the Unity2LA layer.

In this Layout, you will see a Spout Listener node. 

If you select it, you will see it has our Spout Reader node selected as the parent device. This means that this Listener node will output from its Output purple texture pin whichever texture our Spout Reader node in the Devices window is receiving.

To explain the rest of this purple Texture chain originating in our Spout Listener node: first, we connect the texture to Set Texture Channel node, which overwrites the alpha channel of the texture in order to make the sky opaque too. Then we bring the resulting texture to Render to Canvas node, which renders it to a LightAct canvas and from there it goes to the Video screen

For more information about how content flows in LightAct please refer to LightAct Resources in Beginners links above.

In the next article, we will explain how to set up data sharing in LightAct for Unity.

LightAct and Unity Integration

LightAct’s integration with Unity game engine is done with 2 plugins. Spout4Unity plugin takes care of texture sharing via Spout framework and LightAct4Unity is responsible for data sharing. You can download them for free on our GitHub page.

Using Extremely Simple Unity Project sample

If you’d like to avoid the hassle of downloading and installing the above plugins yourself, you can download an already-made Unity sample project. It was made using Unity 2019.2.12f1

This project works out-of-the-box with Extremely Simple Unity Integration sample LightAct project available in Unity tab on Intro window.

In order to get this integration up and running, your first step should be to open that sample project in LightAct by clicking on Open this project button or on the image.

Once it opens, you’ll see a black video screen and a blue sphere in the Visualizer. 

By the end of this article, you’ll make the video screen display the content from Unity and the sphere will float up and down based on the data from Unity.

Opening & Running Sample Unity project

After you’ve downloaded the sample project you can open it by either:

1. Adding the project folder in Unity Hub and opening it from there or

2. double clicking on Scene.unity file that’s available in /Extremely Simple Unity Project/Assets/Scenes folder.

When the project opens, you’ll see a basic scene. It consists of a ‘screen-like’ plane, a red cube, a blue sphere and a yellow text.

After you click play (provided that you still have LightAct running the sample project in the background), you should see something similar to above. The red cube should start rotating (based on data from LightAct), the ‘screen’ should display a moving color gradient (coming from LightAct), the text should change to ‘Hello from LightAct’ (also based on the data from LightAct). The movement of blue sphere up and down is done with a Unity script.

On LightAct’s side, things should also have changed a bit:

The previously black screen should now display a texture coming from Unity. On top this texture, we also render some text, which is also coming from Unity. The blue sphere in the Visualizer is slowly moving up and down in the same rhythm as the sphere in Unity.

If you want to explore how these 2 projects are done , click on the next article on the sidebar on the left.