Unity/C# WebGL平台如何调用含async/await的JavaScript函数
问题原因
Unity 2020.3等旧版本内置的WebGL编译工具(Emscripten)配套的Node.js版本仅支持ES5语法,无法识别async/await等ES6+特性,直接将.jslib文件中导出的函数声明为async会触发语法编译错误。
解决方案
方案1:封装异步逻辑到自执行函数(最常用)
不要直接将导出函数声明为async,把异步逻辑封装到导出函数内部的自执行async函数中即可绕过编译检查,示例修改如下:
修改后的mylib.jslib代码
mergeInto(LibraryManager.library, { // 运行正常 Foo: function () { window.alert("Hello, world!"); }, // 改后可正常编译 Boo: function (){ // 异步逻辑包在自执行async函数内 (async () => { var s = function (ms) { return new Promise(resolve => setTimeout(resolve, ms)); }; await s(2000); window.alert("Boo!"); // 如需回传结果到C#,调用UnitySendMessage // UnitySendMessage("场景中游戏对象名", "C#回调方法名", "字符串参数"); })(); } });
方案2:异步逻辑外置
将包含async/await的JS逻辑写到WebGL打包后的index.html文件,或引入的外部独立JS文件中,.jslib仅作为桥接层调用全局的异步方法即可,完全避开Emscripten的语法检查。
C#端适配
JS端的异步逻辑不会阻塞C#主线程,因此C#无法同步等待异步执行结果,需采用回调方式接收结果:
- 在C#中声明接收回调的公共方法,挂载到场景内指定名称的游戏对象上
[DllImport("__Internal")] private static extern void Foo(); [DllImport("__Internal")] private static extern void Boo(); void Start(){ Foo(); Boo(); } // JS异步执行完成后调用的回调方法 public void OnBooCompleted(string result) { Debug.Log($"JS异步执行结束,返回结果:{result}"); // 此处写后续处理逻辑 }
- JS异步逻辑执行完成后调用
UnitySendMessage("游戏对象名", "OnBooCompleted", "返回结果")即可触发C#回调。
注意事项
UnitySendMessage仅支持字符串类型参数,复杂结构可转JSON字符串后传递- 若项目允许升级,Unity 2021及以上版本内置的Emscripten版本已支持更高版本JS语法,也可通过升级Unity版本解决该问题
内容的提问来源于stack exchange,提问作者CloudL
相关产品推荐
相关产品推荐

