Intermodulation between Unity Web and Js (MQTT Communication)

@ TOC has stepped on a lot of pitfalls about the intermodulation between Unity and Js (MQTT communication). Let’s summarize it next.

general idea

The engineering project was converted from a PC-side project to a Web-side project. The communication method used on the PC side is the MQTT communication subscription terminal, and if it is published on the Web side, MQTT communication cannot be performed directly, so I thought of a way to intermodulate between Unity and JS, write the MQTT subscription terminal to receive messages through JS, and then Then call the method that Unity has written to receive the message, and finally complete the real-time reception of the message (the message is about once a second).

Tell me about your problems

1. I use the Unity2020.3.4 version, and call the Unity method through Js.

Because I really don't understand JS, I can't call it all the time, and I haven't tried the method of searching the Internet, so I can only check it step by step by myself. At the end, I found a post that explained the calling problem (https://forum.unity.com/threads/unity-2020-1-sendmessage-no-longer-works-help.842209/#post-6280073), if the last If you can't try it, you can use my method. The following code is the code in the index.html file after publishing the web terminal (this is a partial code screenshot, the complete code has been placed below), after you open it, you can find the code here.

In the published file script, declare UnityInstance(window .unityInstance=null;), and then assign the Unity Instance in the UnityInstance event (window.unityInstance=unityInstance;), and then refer to it. The two lines written above are just to pave the way for the call. The picture below is to use the SendMessage method to call the method written by Unity.

It can be used in any way as long as it is in the format specified by the JS script.
The method called in Unity
Regarding SendMessage ("object in the Unity scene", "function name in the script on the object (here is the method of receiving the message)", the parameters passed in), if you still don't understand, look for similar posts. This solves the problem of JS calling the Unity method.

2. MQTT communication part (JS part)

If you don't have a colleague who knows JS and you don't know JS, it's a bit uncomfortable. Why do you say that? Because I need to use JS to write the newsletter, but it’s okay, seeing this post is our fate, I will put the referenced file in the post, and the main text begins. . . .
Download the file in my post (it contains three .Js files) and place it under the published Unity project folder.
js file
Next, open the "Index.html" script. At the top of the script, you will see the content of the following picture , and then quote the .js file
insert image description here
(my colleague said that it seems to be enough to quote one, and I haven’t tested which one to quote, and you will test it out and give me a comment below) After all the above are done, the rest is just
communication (Be sure to check the IP and port number with the release end!!!!)

This place should be emphasized. If you still can’t test it, learn about "ws" and "wss" and check it with the release end. For testing, you can use this post (https://blog.csdn.net/qq_17627195/article/details/127301964?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167843521816800222821542%25 22%252C%2522scm%2522%253A %252220140713.130102334.pc%255Fall.%2522%257D&request_id=167843521816800222821542&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2 all first_rank_ ecpm_v1~hot_rank-11-127301964-null - null.142 v73 pc_search_v2,201v4 add_ask,239 v2 insert_chatgpt&utm_term=JS%20MQtt&spm=1018.2226.3001.4187)
It’s almost the same after writing, if it still doesn’t work, don’t panic, there may be problems in the details.
Also, if you publish the Unity Web side, you should test it in the local environment of Build And Run. If you see an error report, there will be an error in Ctrl+Shift+I. Let me put the "index.html" script code

<!DOCTYPE html>
<html lang="en-us">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Unity WebGL Player | Lng_2.0.2</title>
    <link rel="shortcut icon" href="TemplateData/favicon.ico">
    <link rel="stylesheet" href="TemplateData/style.css">
    <script src="./jquery-3.5.1.js"></script>
    <script src="./sockjs.min.js"></script>
    <script src="./stomp.js"></script>
  </head>
  <body>
    <div id="unity-container" class="unity-desktop">
      <canvas id="unity-canvas" width=960 height=600></canvas>
      <div id="unity-loading-bar">
        <div id="unity-logo"></div>
        <div id="unity-progress-bar-empty">
          <div id="unity-progress-bar-full"></div>
        </div>
      </div>
      <div id="unity-warning"> </div>
      <div id="unity-footer">
        <div id="unity-webgl-logo"></div>
        <div id="unity-fullscreen-button"></div>
        <div id="unity-build-title">Lng_2.0.2</div>
      </div>
    </div>
    <script>
      var container = document.querySelector("#unity-container");
      var canvas = document.querySelector("#unity-canvas");
      var loadingBar = document.querySelector("#unity-loading-bar");
      var progressBarFull = document.querySelector("#unity-progress-bar-full");
      var fullscreenButton = document.querySelector("#unity-fullscreen-button");
      var warningBanner = document.querySelector("#unity-warning");

      // Shows a temporary message banner/ribbon for a few seconds, or
      // a permanent error message on top of the canvas if type=='error'.
      // If type=='warning', a yellow highlight color is used.
      // Modify or remove this function to customize the visually presented
      // way that non-critical warnings and error messages are presented to the
      // user.
      function unityShowBanner(msg, type) {
    
    
        function updateBannerVisibility() {
    
    
          warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
        }
        var div = document.createElement('div');
        div.innerHTML = msg;
        warningBanner.appendChild(div);
        if (type == 'error') div.style = 'background: red; padding: 10px;';
        else {
    
    
          if (type == 'warning') div.style = 'background: yellow; padding: 10px;';
          setTimeout(function() {
    
    
            warningBanner.removeChild(div);
            updateBannerVisibility();
          }, 5000);
        }
        updateBannerVisibility();
      }

      var buildUrl = "Build";
      var loaderUrl = buildUrl + "/WebGLTest.loader.js";
      var config = {
    
    
        dataUrl: buildUrl + "/WebGLTest.data.gz",
        frameworkUrl: buildUrl + "/WebGLTest.framework.js.gz",
        codeUrl: buildUrl + "/WebGLTest.wasm.gz",
        streamingAssetsUrl: "StreamingAssets",
        companyName: "DefaultCompany",
        productName: "Lng_2.0.2",
        productVersion: "0.1",
        showBanner: unityShowBanner,
      };

      // By default Unity keeps WebGL canvas render target size matched with
      // the DOM size of the canvas element (scaled by window.devicePixelRatio)
      // Set this to false if you want to decouple this synchronization from
      // happening inside the engine, and you would instead like to size up
      // the canvas DOM size and WebGL render target sizes yourself.
      // config.matchWebGLToCanvasSize = false;

      if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
    
    
        container.className = "unity-mobile";
        // Avoid draining fillrate performance on mobile devices,
        // and default/override low DPI mode on mobile browsers.
        config.devicePixelRatio = 1;
        unityShowBanner('WebGL builds are not supported on mobile devices.');
      } else {
    
    
        canvas.style.width = "960px";
        canvas.style.height = "540px";
      }
      loadingBar.style.display = "block";

      window.unityInstance=null; // 后来添加的

      var script = document.createElement("script");
      script.src = loaderUrl;
      script.onload = () => {
    
    
        createUnityInstance(canvas, config, (progress) => {
    
    
          progressBarFull.style.width = 100 * progress + "%";
        }).then((unityInstance) => {
    
    

          window.unityInstance=unityInstance; //后来添加的
          loadingBar.style.display = "none";
          fullscreenButton.onclick = () => {
    
    
            unityInstance.SetFullscreen(1);
          };
        }).catch((message) => {
    
    
          alert(message);
        });
      };
      document.body.appendChild(script);

       // MQTT通讯       
    var destination = "/topic/LNG.6FS";
    var onconnect = function (frame) {
    
    
      client.subscribe(destination, function (message) {
    
    
        window.unityInstance.SendMessage("Canvas", "CallJS_Message", message.body); //调用Unity 的方法  第三个是传入的参数

        console.log("打印:" + message.body);
      });
    } 
    function ReturnValueFunction() {
    
    
      var url = "ws://10.17.51.103:61614/stomp"; // 端口号这一定要和后端对好,容易错。(因为C#那边MQTT连接是没有端口号的)
      var login = "admin";
      var passcode = "admin";  
      client = Stomp.client(url);     
      client.connect(login, passcode, onconnect);
    }
    //执行
    ReturnValueFunction();
    </script>
  </body>
</html>

Here is the file link (there is also a script inside)
: https://pan.baidu.com/s/1K9S88m6jPGNf4pEiYJfckw
Extraction code: 8rjk

If you have any questions in the future, please add me Q 1497132865

Guess you like

Origin blog.csdn.net/quailchivalrous/article/details/129442127