@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