Unity——Js和Unity互相調用
Unity項目可以打包成WebGl,打包後的項目文件:
Build中是打包後的Js代碼;
Index.html是web項目的入口,裏面可以調整web的自適應,也可以拿去嵌套;
TemplateData是打包時候選的webGl模板;
web端遊戲可能Unity只負責做遊戲部分,而官網由另外的團隊製作,之間就需要Unity和Js代碼之間的相互調用;
Unity調用JavaScript
聲明一下,這裡說的都是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());
}
}
新方法多了可以返回值,但是每次修改必須打包才能測試;
JavaScript調用Unity
這裏面有巨坑,天坑,人都坑傻了!!!
官方文檔中有這幾行字
恰好我用的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>