Godot 导出到 HTML5 实践

作者:art9
2021-11-16
7 3 1

Godot 游戏简介

Godot 是一款免费开源的游戏制作引擎。它也非常轻量级,整个安装包不到 100M,却又功能齐全,易于上手。作为一个后期之秀,Godot 并未得到多少关注,尤其是中文的社区资料就比较少。但如果你在 github 上搜索 “game” 或者 “game engine”,按照星标数排序,就能看到 Godot 以 43.7k star 排名第一,紧随其后的分别是 pixijs(34.7k star)和 phaser (30.7k star)。

它的引擎整个是开源的,并且是 MIT 协议,这也就意味着你可以在它的代码上改一改,就可以宣布自己做了个游戏引擎,要拿出去商用也都是可以的。引擎制作的游戏可以导出到多个平台,如 Windows、Linux、Android、iOS、Web 等等。

Canvas、WebGL、WebAssembly

现如今如果要在以浏览器内核运行游戏,你就会频繁听到以上这些概念。他们都与 JavaScript 有点关系,但彼此又不太相同。Canvas 其实是 HTML5 的一部分,可以用脚本去控制一些 2D 元素的渲染。而 WebGL 则脱胎于 OpenGL,是一套图形的 API 标准,可以在 Web 端渲染 3D 的图像。WebGL 是 OpenGL 的 web 实现,主要用于在浏览器上展示 3D 图形的底层图形技术。

这样,网页端游戏的第一大类实现,就是基于 WebGL 的,例如微信小程序、Cocos Creator、Pixijs 等。

拿微信小游戏举例,它其实是封装了一层 runtime 环境,从底层操作系统开始,封装出了一层 Javascript API,它和 WebGL 长得一样。上层的使用者(如 Cocos )就基于这层接口做开发。但这个 runtime 又是一层阉割版的浏览器内核,它实现 HTML5 的部分内容。如果要操作原生 DOM,这在 chrome 里是可以,但在小程序的 runtime 里就不行。参考 https://forum.cocos.org/t/faq/54842

而 WebAssembly 则可以看作是汇编版的 JavaScript,弥补 JavaScript 在执行效率上的缺陷。可以通过 Emscripten 这样的工具,直接从 C/C++ 程序编译出可以在网页端运行的二进制代码。参考 https://developer.mozilla.org/zh-CN/docs/WebAssembly/Concepts


这也就意味着,如果以 C++ 写的引擎代码,可以直接编译到网页端运行,以 JS 作为胶水来粘合。这就形成了网页端游戏的第二大类实现,我们说它是基于 WebAssembly 的,把游戏引擎搬到了网页中,例如 Unity、Godot 等。这里的引擎有 WebGL 的部分,也有其他的(例如物理系统等等)。

包的导出

在 Godot 中导出到网页的操作是比较容易的,选择 Project -> Export,添加 HTML5 的导出模板即可。在添加之后,工具栏上也会出现一个按钮,点击之后可以直接在网页端预览效果,十分地方便,如下图所示:


打开导出的文件,主要会包含 index.html、index.pck、index.wasm,还有一些 js 的胶水文件。index.pck 是场景、素材、资源文件的打包,而 index.wasm 即是游戏的引擎文件。占据主要大小的是后两者。

关于 pck 文件及优化

一般来说,pck 文件中会包含场景(.tscn)、脚本(.gd),还有资源(.jpg, .ttf)等。代码和场景都还好,一般占大头的是图片等资源。对于特别大的图片,可以选中图片资源、双击,切换到 Import 选项卡,在 Compression 的模式中选择 Lossy(有损),如下图所示:

更多的导入选项可以参考文档 

关于 wasm 文件及优化

默认导出的 wasm 大概有 18M 左右(可能随版本会有差异),里面包含了整个引擎的所有功能。换句话说,哪怕只是做了一个空的项目,导出的 wasm 也是一样的,因为 wasm 就相当于一个 exe 执行文件。其实并非所有的引擎功能都是需要的,例如只是做个 2D 游戏的话,3D 部分的代码就不需要了。

Godot 提供了通用模板的方式,允许使用者按照他自己的实际情况来开/关某些模块。也就是说,你可以通过重新编译源代码的方式,来生成你自己专属的 wasm。官方文档其实写的很详细了,但是第一次看还是会蛮头大的,这里面其实还是有很多潜在坑的。

如果想要自己定制引擎,首先需要在 github 上克隆最新的仓库代码,并且切换到指定的分支。

#Get Godot repo
git clone https://github.com/godotengine/godot.git
cd godot

# List remote branch and checkout one of them (e.g. 3.4)
git branch -r
git checkout 3.4

然后参考这个教程 https://docs.godotengine.org/en/stable/development/compiling/compiling_for_web.html,按照顺序按照 Emscripten 、Python 和 Scons。

安装 Emscripten 的时候参考官网通过代码来安装,只需要执行:

# Get the emsdk repo
git clone https://github.com/emscripten-core/emsdk.git

# Enter that directory
cd emsdk

# Download and install the latest SDK tools.
python emsdk.py install latest

# Make the "latest" SDK "active" for the current user. (writes .emscripten file)
python emsdk.py activate latest

# Activate PATH and other environment variables in the current terminal
source ./emsdk_env.sh

默认的 Emscripten 安装脚本有点问题,尤其是在先前已经安装过 python 的情况下,这里根据自己的情况改,然后使用 pip install scons 安装 scons

然后就可以按照之前的文档去进行构建了,可以先运行 scons platform=list 查看有哪些打包环境可用。(对于导出到网页端来说,如果不安装 emsdk,就无法进行到下一步)

最简单的,可以用 scons platform=javascript tools=no target=release 来打包一个 Release 环境的包。

那么,如何针对性的选择要开启/关闭哪些功能呢,可以参考文档上的说明,但更快的方式是,使用一个 custom.py 模板。进入到下面这个页面 https://godot-build-options-generator.github.io/ ,在左侧勾选你需要或者不需要的模块,就可以在右侧生成一个 python 文件,如下图所示:

把这个文件丢到引擎的源代码根目录,再运行 scons 的时候,就能够识别到了。它会在 bin 目录下生成一个 zip 文件。这个文件需要放置到导出窗口下的 Custom Template,如下图所示,在每次导出前配置即可。

使用的定制模板导出的文件大小,就会在把 3d 模块、视频播放等一些不必要模块去掉以后,生成的 wasm 大小可以压缩到 10M 以内,优化了一半大小。(这里需要注意的是,如果开启了图片有损压缩,那就需要把 webP 功能打开,不然会 error)

进一步优化

同时,如果在服务端能够开启 gzip 压缩,则能够进一步地减小包传送的大小,经过测试,10M 左右的包在开启压缩以后,只传送了 2.8M 的数据,只有原来的 1/3 大小了,如下:

小结

以上便是,在用 Godot 引擎导出到网页端的一些具体的实践。通过上面的操作,可以显著降低导出包的大小,希望能对你有所帮助。

本文为用户投稿,不代表 indienova 观点。

近期点赞的会员

 分享这篇文章

art9 

懂点数学的玩家 

您可能还会对这些文章感兴趣

参与此文章的讨论

  1. 谷木工作室 2021-11-17

    好起来了,两年前我刚接触godot时候,godot还特别小众,现在越来越多的人开始用godot了。GODOT,独立游戏开发者的神!

您需要登录或者注册后才能发表评论

登录/注册