Unity项目可以打包成WebGl,打包后的项目文件:
Build中是打包后的Js代码;
Index.html是web项目的入口,里面可以调整web的自适应,也可以拿去嵌套;
TemplateData是打包时候选的webGl模板;
web端游戏可能Unity只负责做游戏部分,而官网由另外的团队制作,之间就需要Unity和Js代码之间的相互调用;
声明一下,这里说的都是Unity和外部JS代码的互相调用,项目内调用有其他方法;
老版本提供一个过时的方法:
1.在WebGL项目中的Index.html中添加要调用的JS方法
function Unity2JavaScript() { alert("UnityToWeb") }
2.Unity中调用
Application.ExternalCall("Unity2JavaScript"); //可以有参数,没有返回值 //Application.ExternalCall("Unity2JavaScript",a,10,"aaaa");
Unity建议使用的方法:
1.在Plugins文件夹中,创建后缀为.jslib的文件,在其中写需要调用的js代码
mergeInto(LibraryManager.library, { Hello: function () { window.alert("Hello, world!"); }, HelloString: function (str) { window.alert(Pointer_stringify(str)); }, PrintFloatArray: function (array, size) { for(var i = 0; i < size; i++) console.log(HEAPF32[(array >> 2) + size]); }, AddNumbers: function (x, y) { return x + y; }, StringReturnValueFunction: function () { var returnStr = "bla"; var buffer = _malloc(lengthBytesUTF8(returnStr) + 1); writeStringToMemory(returnStr, buffer); return buffer; }, BindWebGLTexture: function (texture) { GLctx.bindTexture(GLctx.TEXTURE_2D, GL.textures[texture]); }, });
2.Unity中调用——__Internal.jslib
using UnityEngine; using System.Runtime.InteropServices; public class NewBehaviourScript : 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); 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()); } }
新方法多了可以返回值,但是每次修改必须打包才能测试;
这里面有巨坑,天坑,人都坑傻了!!!
官方文档中有这几行字
恰好我用的2020版本的Unity;
主要使用这个API——
SendMessage("游戏对象名","方法名","参数"); 这个和参数和lua调用c#差不多了,但是怎么调用这个api就很玄学了;
首先如果你调用这个方法需要在Unity的资源已经加载完成才可以,这个好解决,js加个button;
<button Type="button" onclick="TestSend()">WebToUnity</button>
其次在调用这个方法前需要先实例化UnityInstance变量;
var gameInstance = null; script.onload = () => { gameInstance = createUnityInstance(document.querySelector("#unity-canvas"), { dataUrl: "Build/Test.data", frameworkUrl: "Build/Test.framework.js", codeUrl: "Build/Test.wasm", streamingAssetsUrl: "StreamingAssets", companyName: "DefaultCompany", productName: "UnityToWeb", productVersion: "0.1", }); }; //以上的参数都可以在unity的playersetting界面找到;
最后调用时要在then中用lamda表达式
function TestSend() { gameInstance.then((unityInstance) => { unityInstance.SendMessage("Canvas","OnLogin","dqwreqweraf"); }); }
完整的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 | UnityToWeb</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"> <button Type="button" onclick="TestSend()">WebToUnity</button> <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-mobile-warning"> WebGL builds are not supported on mobile devices. </div> <div id="unity-footer"> <div id="unity-webgl-logo"></div> <div id="unity-fullscreen-button"></div> <div id="unity-build-title">UnityToWeb</div> </div> </div> <script> var buildUrl = "Build"; var loaderUrl = buildUrl + "/Test.loader.js"; var config = { dataUrl: buildUrl + "/Test.data", frameworkUrl: buildUrl + "/Test.framework.js", codeUrl: buildUrl + "/Test.wasm", streamingAssetsUrl: "StreamingAssets", companyName: "DefaultCompany", productName: "UnityToWeb", productVersion: "0.1", }; 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 mobileWarning = document.querySelector("#unity-mobile-warning"); // 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; mobileWarning.style.display = "block"; setTimeout(() => { mobileWarning.style.display = "none"; }, 5000); } else { canvas.style.width = "960px"; canvas.style.height = "600px"; } loadingBar.style.display = "block"; var script = document.createElement("script"); script.src = loaderUrl; var gameInstance = null; script.onload = () => { gameInstance = createUnityInstance(document.querySelector("#unity-canvas"), { dataUrl: "Build/Test.data", frameworkUrl: "Build/Test.framework.js", codeUrl: "Build/Test.wasm", streamingAssetsUrl: "StreamingAssets", companyName: "DefaultCompany", productName: "UnityToWeb", productVersion: "0.1", }); }; function TestSend() { gameInstance.then((unityInstance) => { unityInstance.SendMessage("Canvas","OnLogin","dqwreqweraf"); }); } document.body.appendChild(script); </script> </body> </html>