@TOC关于Unity与Js互调(MQTT通讯篇)踩了很多坑接下来总结一下
总体思路
工程项目当时是PC端项目转成Web端项目。PC端采用的通讯方式是MQTT通讯订阅端,而如果发布成Web端的话不能直接进行MQTT通讯,就想了个办法通过Unity与JS互调的的方法,通过JS写MQTT订阅端接收消息,然后再调用Unity已经写好接收消息的方法,最后完成信息实时接收(消息大约1秒一次)。
说说自己遇到几个问题
1.自己用的Unity2020.3.4版本,通过Js去调用Unity方法。
因本人确实不懂JS,导致始终调用不到,搜索网上的方法也没试成功,就只能自己一步一步去排查。到最后找到一个帖子,就是讲解的调用问题(https://forum.unity.com/threads/unity-2020-1-sendmessage-no-longer-works-help.842209/#post-6280073),如果最后尝试不行的话,可以使用我这种方法。以下代码是发布web端之后的index.html文件中代码(这是部分代码截图,完整代码已经放在下面了),打开以后你找到此处代码
在已经发布出文件脚本中,声明一下UnityInstance(window.unityInstance=null;),然后给UnityInstance赋值事件中的Unity Instance(window.unityInstance=unityInstance;), 通过这样再引用。前面写的两行只是为了给调用做铺垫,下面图片是使用SendMessage方法调用Unity写好的方法。
只要在JS脚本规定的格式中怎么用都可以。
关于SendMessage(“Unity场景中物体”,“物体上脚本中函数名称(此处是接收消息的方法)”,被传入的参数)如果还是不明白就找找类似的帖子。这样就解决了JS调用Unity方法的问题。
2. MQTT通讯部分(JS部分)
如果你没有会JS的同事而你也不会JS那就有点难受咯,为啥子这样说尼?因为要用JS写通讯哦,不过也没事,看到此贴乃是我们的缘分,我会把引用的文件放在帖子里,好了正文开始了。。。。
下载好我帖子中的文件(里面包含三个.Js文件)放在已经发布完的Unity项目文件夹下面
接下来还是打开“Index.html”脚本,在脚本最上边你会看到以下图片上内容,然后再去引用.js文件
(我同事说好像引用一个就可以,我也没测试到底引用哪一个,后续你们测试出来给我底下评论下)
以上都做完的话,剩下就通讯就可以了(一定要和发布端对好Ip和端口号!!!!)
这个地方要着重说一下,如果还是测不通 了解一下“ws”和“wss”然后和发布端一起对一下。测试方面的话可以用这个帖子(https://blog.csdn.net/qq_17627195/article/details/127301964?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167843521816800222821542%2522%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-2allfirst_rank_ecpm_v1~hot_rank-11-127301964-null-null.142v73pc_search_v2,201v4add_ask,239v2insert_chatgpt&utm_term=JS%20MQtt&spm=1018.2226.3001.4187)
写到这就差不多了,如果还是不通,莫慌 可能是细节方面出现了问题。
还有发布UnityWeb端的话应Build And Run 本地环境测试一下,看报错的话Ctrl+Shift+I 里面会有出现的错误。下面我放一下“index.html”脚本代码
<!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>
下面是文件链接(里面也有脚本)
链接:https://pan.baidu.com/s/1K9S88m6jPGNf4pEiYJfckw
提取码:8rjk
如果后续还有问题可以加我Q 1497132865