导读:本文主要是介绍下wasm的开发跟使用环境,后面关键说明如何使用Rust的wasm-pack打包出来的wasm程序,并在cocoscreator中导入并使用。
如果没了解过这一块的,建议从头开始读读,我分享了一些这半年来收集的相关资料。
如果您之前已经了解过Rust开发,并且能将wasm打包出来的,但还没在CocosCreator的环境运行起来的,可以直接跳过前面资料部分,看《在cocoscreator使用wasm的几个关键点》。
wasm的环境支持,可以看上面这张图。大抵的意思就是旧的不行,新的基本上没问题,都支持。
在移动端除了 android 4.4 和 ios 10 下不支持外,其他版本都能提供支持。还需要注意的是 wasm 有可能占用大量内存,使用第三方包含 wasm 调用的组件需要注意内存占用防止闪退。
wasm模块 可以用多种语言来编译,包括 C/C++/C#、Rust、JAVA、Go。在这里使用 Rust 是因为它有严格的内存管理机制,从语法上尽量避免内存溢出,让工程师写出更安全的程序。
https://docs.cocos.com/creator/manual/zh/scripting/wasm-support.html
cocos官网文档对WebAssembly的描述,这里也表明了,一些旧的环境下,是不支持wasm的,所以要不要使用,还是可以看下上面的支持环境再做决定。
什么环境下才有必要使用wasm
-
wasm可以使用二进制程序处理一些计算量大的处理。
-
加密代码,因为编译成二进制程序了,所以反编译出来,阅读困难程度还是超级加倍滴。
-
相反的,如果只是简单的隐藏调用的小部分代码,使用wasm时会有大量的js跟wasm的转换跟调用,反而会有点点影响效率。
-
如果想在微信小游戏环境下使用wasm来避过审核机制,这个是不行的,这个会在最后面微信小游戏的使用中说明为什么。
Rust主要四大模块
-
命令行工具:用来做一些项目的辅助工具非常方便,Rust有成熟的库(crate.io)编译出来的可执行文件又小,运行速度也相当滴快。
-
WebAssembly:您懂的~
-
网络程序开发:无论是网络客户端还是服务器,转发端都是非常推荐的,独有的程序语言特点,让它拥有速度快,稳定性强,还有内存安全等特点。
-
嵌入式开发:还没多了解,有兴趣的话请自动查看下官方文档 https://www.rust-lang.org/what/embedded
Rust开发wasm相关的学习资源
Rust官网 https://www.rust-lang.org/
https://doc.rust-lang.org/book/
Rust的基础教程,主要是看看各种语法的使用,学习时请多关注下借用及所有权,这点在Rust语言中比较新鲜,刚学习时会有点不适,多练习就习惯了。
https://rustwasm.github.io/docs/book/
Rust开发wasm的基础教程,包括wasm-pack的安装使用
https://rustwasm.github.io/docs/wasm-bindgen/examples/index.html
Rust开发wasm的一些官方实例,特别注意下,这里展示的web_js库在浏览器是没问题的,但cocos的安卓版本中是没跑起来的,所以如果有原生的需求,请避开用这个库。
https://crates.io/
Rust的三方库,有很多高质量的轮子可以用,省去了很多功夫。
刷一遍上面的教程,基本上用来开发Rust是够够的。如果您的学习时间有限,也可以学下rust与wasm的基础教程即可,剩下的有需要的时候再找资料。
在cocoscreator使用wasm的几个关键点
-
打包,wasm-pack可以将wasm打包到不同的环境中(bundler, nodejs, web, no-modules)使用。由于我们要用在cocoscreator的web或原生端中,所以这里选择web环境。
-
打包时记得给命令增加一个–release的标记,打出来的程序会小一些。
-
打包命令里加上 --no-typescript 的标记,这里我们用不上这个ts的描述文件,直接使用js文件来运行wasm。并且,把生成的js文件,后缀名改成.ts,方便使用。
-
生成出来的wasm文件,在原生端里使用,要通过二进制的形式去加载,目前我找到的方式是把文件扩展名改成.bin。
-
在项目里写一个Component,然后声明一个BufferAsset,把上面生成的.bin文件挂进去
@property(BufferAsset) wasm_asset!: BufferAsset;
- 引用wasm-pack打包出来的js文件里的默认方法:
import { initSync } from "kkwasm"; // 这里kkwasm为您导出的js文件
- 找个方法把wasm引入并初始化。
start_init_api() {
let wasm_buffer: ArrayBuffer | string = this.wasm_asset?.buffer();
initSync(wasm_buffer);
}
-
至此,wasm的初始化就完成了。您在rust代码里实现的所有方法,结构体,都可以在这里完成后开始使用。
-
在微信小游戏环境中的使用。微信官方应该是对wasm的引入做了特殊处理,所以要用这样的方法来导入wasm。这也是上面说过不能用wasm来规避审核的原因。
-
这里的初始化就不能用二进制文件了,要保留wasm-pack生成的.wasm扩展名。
可以走cocoscreator的build-templates方式,把.wasm的文件拷进去,这样每次发布微信小游戏的时候就不需要再手动去拷贝到项目里。 -
初始化的方法还是用第6步引入的方法initSync,这里还要对生成的js文件进行处理。
-
然后在cocos的项目代码里,特殊处理一下在微信小游戏环境中的引入:
initSync("/kkwasm_bg.wasm");
// 假设您生成的wasm程序文件名叫kkwasm_bg.wasm,这个文件要放在微信小游戏的工程目录下
测试过的运行环境
-
web端,chrome及edge的浏览器都测试过,没发现有什么问题。
-
原生端,安卓测试过。ios环境没钱买设备,测不起测不起,盲猜应该是没问题的,因为跟安卓原生端用的同一套底层。
-
微信小游戏,按照上面的流程去设置,也是可以正常测试过的。具体的生产环境应该也是可以。
展望跟构想
-
目前整套流程是可以跑的,我还没应用到具体的生产环境中,所以如果在这方面发力的您,请多做测试之后再使用,避免开发到一半要推倒重来。
-
用js去调用wasm确实挺爽的,我自己写的时候,可以把一些底层代码隐藏起来,还能编译一些rust的库过来用。不用重复造轮子,还能得到更高的效率。
-
wasm的使用还是有很大的意义的。像unity打包成webgl,甚至到微信小游戏,抖小等等环境,也是把底层打包成wasm。
-
我选择rust来写wasm,是因为它确实带来了很多方便的地方,虽然目前还没有百分百地如意,但能在项目中使用wasm,还是有机会能提升一部分的游戏性能的。
-
如果您喜欢这篇分享,帮忙点个赞呗,收藏下。谢谢~
rust开发wasm并在cocoscreator中使用的实例: