赞
踩
Unity
: 2021.3
stomp.js 2.3.3
:下载地址
:https://www.jsdelivr.com/package/npm/stompjs
这篇博客的主要内容是记录将一个
Unity
项目打包成WebGL
项目,并集成MQTT
UI
界面和元素将系统中的字体文件导入
Unity
详情参考:Unity3D添加使用系统中的字体
3. 添加插件
用于解决
WebGL
中输入框无法输入/显示中文的问题
详情参考:
Unity WebGL 输入框(InputField)接受中文输入
unity在webgl端 输入框无法输入中文和中文显示问题的解决
下载地址: 使用github包【WebGLInput】:
https://github.com/kou-yeung/WebGLInput
.jslib
文件详细内容参考:Unity(WebGL)与JS通讯2022最新姿势
mergeInto(LibraryManager.library, { Hello: function () { window.alert("Hello, world!"); }, HelloString: function (str) { // window.alert(Pointer_stringify(str)); window.alert(UTF8ToString(str)); }, PrintFloatArray: function (array, size) { for(var i = 0; i < size; i++) console.log(HEAPF32[(array >> 2) + i]); }, AddNumbers: function (x, y) { return x + y; }, StringReturnValueFunction: function () { var returnStr = "bla"; var bufferSize = lengthBytesUTF8(returnStr) + 1; var buffer = _malloc(bufferSize); stringToUTF8(returnStr, buffer, bufferSize); return buffer; }, BindWebGLTexture: function (texture) { GLctx.bindTexture(GLctx.TEXTURE_2D, GL.textures[texture]); }, Connect: function (host, port, clientId, username, password, destination) { mqttConnect(UTF8ToString(host), UTF8ToString(port), UTF8ToString(clientId), UTF8ToString(username), UTF8ToString(password), UTF8ToString(destination)); }, Subscribe: function (topic) { mqttSubscribe(UTF8ToString(topic)) }, Send: function (topic, payload) { mqttSend(UTF8ToString(topic), UTF8ToString(payload)) }, Unsubscribe: function(topic) { mqttUnsubscribe(UTF8ToString(topic)); }, Disconnect: function() { mqttDisconnect(); } });
Cube
添加脚本用于显示基本函数功能
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Runtime.InteropServices; public class Cube : MonoBehaviour { [DllImport("__Internal")] private static extern void Hello(); [DllImport("__Internal")] private static extern void HelloString(string str); [DllImport("__Internal")] private static extern void PrintFloatArray(float[] array, int size); [DllImport("__Internal")] private static extern int AddNumbers(int x, int y); [DllImport("__Internal")] private static extern string StringReturnValueFunction(); [DllImport("__Internal")] private static extern void BindWebGLTexture(int texture); [System.Obsolete] void Start() { Hello(); HelloString("This is a string."); float[] myArray = new float[10]; PrintFloatArray(myArray, myArray.Length); int result = AddNumbers(5, 7); Debug.Log(result); Debug.Log(StringReturnValueFunction()); var texture = new Texture2D(0, 0, TextureFormat.ARGB32, false); BindWebGLTexture(texture.GetNativeTextureID()); } }
Canvas
添加脚本PanelController.cs
用于测试
mqtt
相关函数
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Runtime.InteropServices; using UnityEngine.UI; public class PanelController : MonoBehaviour { [DllImport("__Internal")] private static extern void Connect(string host, string port, string clientId, string username, string password, string destination); [DllImport("__Internal")] private static extern void Subscribe(string topic); [DllImport("__Internal")] private static extern void Send(string topic, string payload); [DllImport("__Internal")] private static extern void Unsubscribe(string topic); [DllImport("__Internal")] private static extern void Disconnect(); public Button connectBtn; public Button subscribeBtn; public Button sendBtn; public Button unsubscribeBtn; public Button disconnectBtn; private InputField hostInput; private InputField portInput; private InputField clientIdInput; private InputField usernameInput; private InputField passwordInput; private InputField destinationInput; private InputField topicInput; private InputField messageInput; private Text scrollLogText; // Start is called before the first frame update void Start() { connectBtn.onClick.AddListener(HandleConnect); subscribeBtn.onClick.AddListener(HandleSubscribe); sendBtn.onClick.AddListener(HandleSend); unsubscribeBtn.onClick.AddListener(HandleUnsubscribe); disconnectBtn.onClick.AddListener(HandleDisconnect); foreach (UnityEngine.UI.InputField textInput in GetComponentsInChildren<UnityEngine.UI.InputField>()) { // Debug.Log(textInput.name); switch (textInput.name) { case "host_input": { hostInput = textInput; break; } case "port_input": { portInput = textInput; break; } case "client_id_input": { clientIdInput = textInput; break; } case "username_input": { usernameInput = textInput; break; } case "password_input": { passwordInput = textInput; break; } case "destination_input": { destinationInput = textInput; break; } case "topic_input": { topicInput = textInput; break; } case "message_input": { messageInput = textInput; break; } } } foreach (Text textItem in GetComponentsInChildren<Text>()) { switch (textItem.name) { case "scroll_log_text": { scrollLogText = textItem; break; } } } } void HandleConnect() { Debug.Log("unity: connect"); string host = hostInput.text; string port = portInput.text; string clientId = clientIdInput.text; string username = usernameInput.text; string password = passwordInput.text; string destination = destinationInput.text; Connect(host, port, clientId, username, password, destination); } void HandleSubscribe() { Debug.Log("unity: subscribe"); // string topic = "unity_test"; string topic = topicInput.text; Subscribe(topic); } void HandleSend() { Debug.Log("unity: send"); // string topic = "unity_test"; // string payload = "你好"; string topic = topicInput.text; string payload = messageInput.text; Send(topic, payload); } void HandleUnsubscribe() { Debug.Log("unity: unsubscribe"); string topic = topicInput.text; Unsubscribe(topic); } void HandleDisconnect() { Debug.Log("unity: disconnect"); Disconnect(); } void SetLogScroll(string log) { scrollLogText.text += "\n" + log; } }
WebGL
项目index.html
内容在
html
文件引入其他js
文件的格式,
具体参考: webGl使用jsLib与Js交互
<!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 | Web Demo</title> <link rel="shortcut icon" href="TemplateData/favicon.ico"> <link rel="stylesheet" href="TemplateData/style.css"> </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">Web Demo</div> </div> </div> <!-- 引入stomp.min.js --> <script src="Plugins/stomp.min.js"></script> <script> var client var subscribeIdObj = {} function mqttConnect(host, port, clientId, username, password, destination) { let url = 'ws://' + host + ':' + port + '/stomp' console.log("html: connect " + url); // let host = '127.0.0.1' // let port = '61614' // let clientId = 'example-unity' // let user = 'user' // let password = 'pass' // 创建一个client实例 client = Stomp.client(url) console.log(client) let headers = { login: username, passcode: password, 'client-id': clientId } client.connect(headers, () => { console.log('connect success'); unityInstance.SendMessage('Canvas', 'SetLogScroll', 'connect success') // 订阅主题 subscribeIdObj[destination] = client.subscribe('/topic/' + destination, message => { if (message.body) { console.log('get body : ' + message.body) unityInstance.SendMessage('Canvas', 'SetLogScroll', 'get body : ' + message.body) } else { console.log('get empty message') unityInstance.SendMessage('Canvas', 'SetLogScroll', 'get empty message') } }, () => { console.log('connect failed') unityInstance.SendMessage('Canvas', 'SetLogScroll', 'connect failed') }) }) } function mqttSubscribe(topic) { console.log("html: subscribe " + topic); unityInstance.SendMessage('Canvas', 'SetLogScroll', "html: subscribe " + topic) // 保存topic对应的subscribeId subscribeIdObj[topic] = client.subscribe('/topic/' + topic, message => { if (message.body) { console.log('message body: ' + message.body) unityInstance.SendMessage('Canvas', 'SetLogScroll', 'message body: ' + message.body) } else { console.log('empty message') unityInstance.SendMessage('Canvas', 'SetLogScroll', 'empty message') } }, {id: '1212'}) } function mqttSend(topic, payload) { console.log("html: send " + topic + ", " + payload); unityInstance.SendMessage('Canvas', 'SetLogScroll', "html: send " + topic + ", " + payload) let headers = {} client.send('/topic/' + topic, headers, payload) } function mqttUnsubscribe(topic) { console.log("html: unsubscribe"); unityInstance.SendMessage('Canvas', 'SetLogScroll', "html: unsubscribe") console.log(subscribeIdObj); subscribeIdObj[topic].unsubscribe() } // 断开连接 function mqttDisconnect() { console.log("html: disconnect"); client.disconnect(() => { console.log('disconnect') unityInstance.SendMessage('Canvas', 'SetLogScroll', 'html: disconnect') }) } 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 + "/Web.loader.js"; var config = { dataUrl: buildUrl + "/Web.data", frameworkUrl: buildUrl + "/Web.framework.js", codeUrl: buildUrl + "/Web.wasm", streamingAssetsUrl: "StreamingAssets", companyName: "DefaultCompany", productName: "Web Demo", 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)) { // Mobile device style: fill the whole browser client area with the game canvas: var meta = document.createElement('meta'); meta.name = 'viewport'; meta.content = 'width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, shrink-to-fit=yes'; document.getElementsByTagName('head')[0].appendChild(meta); container.className = "unity-mobile"; canvas.className = "unity-mobile"; // To lower canvas resolution on mobile devices to gain some // performance, uncomment the following line: // config.devicePixelRatio = 1; unityShowBanner('WebGL builds are not supported on mobile devices.'); } else { // Desktop style: Render the game canvas in a window that can be maximized to fullscreen: canvas.style.width = "960px"; canvas.style.height = "600px"; } loadingBar.style.display = "block"; var script = document.createElement("script"); script.src = loaderUrl; script.onload = () => { createUnityInstance(canvas, config, (progress) => { progressBarFull.style.width = 100 * progress + "%"; }).then((unityInstance) => { loadingBar.style.display = "none"; // 为window添加unityInstance对象 window.unityInstance = unityInstance fullscreenButton.onclick = () => { unityInstance.SetFullscreen(1); }; }).catch((message) => { alert(message); }); }; document.body.appendChild(script); </script> </body> </html>
WebGL
项目InputField
不能输入/显示中文参考:
Unity WebGL 输入框(InputField)接受中文输入
unity在webgl端 输入框无法输入中文和中文显示问题的解决
Unity3D添加使用系统中的字体
unityInstance is not defined
参考:
[Unity转小游戏]微信开发者工具/微信小游戏中找不到unityInstance.(unityInstance is not defined)
查找物体和组件
Unity 之 查找游戏物体的几种方式解析
Unity 常用API之Component,GameObject获取组件
Unity与Js互相调用
Unity WebGL C#调用JS脚本
unity开发webGL,引用js功能。
Unity(WebGL)与JS通讯2022最新姿势
webGl使用jsLib与Js交互
Unity在WebGL中InputField无法输入中文
Unity WebGL 输入框(InputField)接受中文输入
unity在webgl端 输入框无法输入中文和中文显示问题的解决
Unity3D添加使用系统中的字体
unityInstance is not defined
[Unity转小游戏]微信开发者工具/微信小游戏中找不到unityInstance.(unityInstance is not defined)
Unity构建WebGL
Unity-WebGL-打包流程以及遇到的各种坑
unity打包webgl 部署到本地Web服务器
【Unity】打包WebGL项目遇到的问题及解决记录
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。