Giter VIP home page Giter VIP logo

unity-webgl-mqtt's Introduction

Unity WebGL MQTT

A sample project to consume MQTT data stream using Unity WebGL and MQTT.JS


Sample Project in folder MQTTWebGL

Demo: https://ucl-casa-ce.github.io/unity-webgl-mqtt/

Prerequisites

  • MQTT broker publishing over a secure WebSocket
  • Unity3D with WebGL build support (version used in this sample 2022.3.2f1)
  • VSCode (or your preferred editor)

Languages used:

  • HTML
  • JavaScript
  • C#

Introduction

The M2MQTT library is the ideal tool to consume MQTT data in Unity3D. However, Unity's WebGL builds do not permit direct access to IP sockets for network connectivity. As a result, we must use WebSockets (more information here). Although Unity3D cannot execute JavaScript files directly, it is feasible to incorporate an external JavaScript library into Unity via the library interface. This interface acts as a bridge, linking the external JavaScript library to Unity’s MonoBehaviour using standard C# scripts.

NOTE: the JS library will only run in the Unity WebGL build and not in the UnityEditor.

Process

JS Library

  • Start by creating a new Unity project. Then, navigate to File -> Build Settings and switch the platform to WebGL.
  • In the Assets folder of the Unity project, create a new folder named Plugins.
  • Using VSCode, create a new JavaScript file named mqttjsPlugin.js within the Plugins folder. The JavaScript library must have a specific syntax to be recognized and utilized by Unity.

NOTE: The JavaScript file should have the extension .jslib. However, it is recommended to initially create it as a .js file. This allows VSCode to provide the correct formatting, making it easier to code.

var mqttjsPlugin={

$DataMqttJs: 
{
    out_msg:"",
    topic:"",
},

mqttConnect: function (brokerAddress,topicSub,callback)
{
  console.log("Connecting to broker");
  var client = mqtt.connect(UTF8ToString(brokerAddress));
  var topic= UTF8ToString(topicSub);
  console.log(topic);

  client.on("connect", () => {
    console.log("Connected");
    client.subscribe(topic);
    client.on('message', (topic, message) => {
    //Called each time a message is received
    console.log('Received message:', topic, message.toString());

    SendMessage('mqttResponse', 'GetData', message.toString());
    })
    });

client.on("error", (error) => {
  console.log(error);
  });
  },
  }
autoAddDeps(mqttjsPlugin, '$DataMqttJs');
mergeInto(LibraryManager.library, mqttjsPlugin);
  • An initial variable is utilized to encapsulate the content of the library.
  • If multiple functions are employed and data needs to be shared among them, global variables can be declared using the $Name_Context syntax and registered using autoAddDeps method. To use them, you will need to access them using Name_Context.Name_Variable, omitting the $ sign.

The function mqttConnect is utilized to:

  • Create the MQTTJs client.
  • Subscribe to the provided topic.
  • Retrieve the MQTT data and send a message to Unity using SendMessage.

In this case, the broker address and the topic are sent to the library from the C# script (we will discuss this shortly). Numeric types do not require any conversion. However, strings need to be converted using the UTF8ToString method.

Finally, the SendMessage method is used to send the data back to the C# script.

The syntax used is SendMessage(objectName, methodName, value); where:

  • objectName refers to a GameObject in the scene. The name must be unique as Unity performs a GameObject.Find operation behind the scenes.
  • methodName refers to the method of the C# script that is attached as a component to the objectName.
  • value is the data sent to Unity from the JS library. It can be a string or a number. Arrays are not supported, but it is possible to send multiple values using JSON. The value can be empty.

The last line of the JS library is mergeInto, which is used to export the library in the WebGL build.

C# Component

To utilize the JavaScript library with Unity, you should create a new C# script named mqttManagerJS.cs. Please note that this script should not be created in the Plugins folder.

using UnityEngine;
using System.Runtime.InteropServices;
using TMPro;

//Version 3
public class mqttManagerJS : MonoBehaviour
{
    public string brokerAdress = "ws://ADDRESS.mqtt.BROKER:8080";
    public string topicSub = "TOPIC/To/Subscribe";
    public TextMeshPro valueMqtt;

    // Import the external JavaScript functions
    [DllImport("__Internal")] private static extern void mqttConnect(string broker, string topic);

    private void Start()
    {
        mqttConnect(brokerAdress, topicSub); //this call the Javascript method
    }

    public void GetData(string message) //this is called from Javascript using the SendMessage method
    {
        Debug.Log("Received string from JavaScript: " + message);
        valueMqtt.text = message;
    }
}
  • The [DllImport("__Internal")] attribute is used to import the functions declared in the JS Library.
  • In the Start method, the component calls the JS function and passes the broker address and topic to subscribe to.
  • In the JS library, the GetData method is called, and the MQTT message is passed to Unity.

Visualise the Data

In this example, a TextMeshPro GameObject is used to visualize the message in Unity:

  • Create a new TMPro GameObject by navigating to GameObject -> 3D Object -> Text - TextMeshPro.
  • Right-click on it from the Hierarchy panel and rename it from Text (TMP) to mqttResponse.

NOTE: The name needs to be unique as it is used in the SendMessage method in the JS library.

  • Adjust the position and font size of the mqttResponse GameObject as needed to keep it visible to the camera.
  • Attach the mqttManagerJS.cs to the mqttResponse object as a new component.
  • From the Hierarchy panel, drag and drop the mqttResponse GameObject itself to the Value Mqtt field.

Build the WebGL App

Navigate to File -> Build Settings, add the Open Scene, and press Build. Unity will then create a folder containing the index.html, entry point of our App, and the data folders.

NOTE: remember to set the public variables Broker Address and Topic Sub of the mqttManagerJS.cs component attached to the mqttResponse TextMeshPro GameObject.

The final step is to add the MqttJs library, which is called by the JavaScript library we created, to the head of the index.html file created by Unity.

     <script src="https://unpkg.com/[email protected]/dist/mqtt.min.js" type="text/javascript"></script> 

The index.html file will run the Unity WebGL application that displays and updates the MQTT message received in real time.

NOTE: By default, Unity builds use GZ compression. If the webserver is not properly configured or if you are running a local web server, it will throw an error (Unable to parse Build/XXXX.framework.js.gz!). In such cases, you can disable the compression by navigating to Project Settings -> Player -> Publishing Settings -> Compression Format -> Disabled. GitHub Pages doesn't support gzip's content.

Common Mistakes

  • The name of the GameObject used in SendMessage is not unique.
  • The data type sent using SendMessage does not match the type received by the C# Script.
  • There are typos in the GameObject name or Method name, particularly with regard to case sensitivity.
  • The JS library is not properly formatted or has an extension other than .jslib.

unity-webgl-mqtt's People

Contributors

vsigno avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.