# Unity WebGL 微信小游戏适配

# 一、概述

欢迎使用Unity WebGL小游戏适配(转换)方案,本方案设计目的是降低 Unity 游戏转换到微信小游戏的开发成本。基于WebAssembly技术,无需更换Unity引擎与重写核心代码的情况下将原有游戏项目适配到微信小游戏。

工具与文档项目开放地址:Unity WebGL微信小游戏适配方案 或使用 Gitee仓库

# 方案特点

# 二、技术原理

Unity的BuildTarget支持WebGL平台,WebGL导出包是基于WebAssembly技术运行在浏览器环境。 为了能让导出包运行在微信小游戏环境,我们提供了以下支持:

# 三、转换案例

本方案适合多种品类的游戏项目

请通过转换案例体验Unity WebGL适配小游戏表现

# 四、接入流程

接入流程主要包含以下几个环节:

注:图中每个环节的人力时间为预计,具体时间因具体项目不同。

# 可行性评估

我们为接入游戏提供了评估表,问卷内容是本转换方案最重要的影响因素。当根据实际项目填写之后与我们联系后一起评估可行性和技术风险点,重要的能力支持情况如下:

能力 是否支持 解决方案
Unity基础模块 支持 支持动画、物理、AI、UI等基础模块
渲染管线与接口 支持 支持标准渲染管线、URP,但依赖WebGL2.0的特性处于Beta测试
资源加载 支持 Addressable、AssetBundle网络异步加载
Lua脚本 支持 支持标准Lua与常见binding(如xlua, tolua等), 不支持Luajit。需根据实际游戏在真机验证性能
PuerTS 支持 iOS系统需14.5以上, 支持JIT
Unity音频 支持 Unity Audio基本能力支持,支持fmod插件,暂未支持wwise。长音频建议适配小游戏音频InnerAudio以优化内存
第三方插件 部分支持 支持大部分插件,C#插件与非平台相关的C原生插件
网络系统 需调整 不支持System.Net接口,HTTP使用UnityWebRequest,WebSocket通信替代(如开源的UnityWebSocket插件),UDP/TCP使用WX SDK适配
多线程 不支持 删除多线程用法,使用异步等其他替代方式
文件系统 需调整 不支持System.File,但可使用微信小游戏WX SDK实现文件存储,大小限制为200MB(满足条件可申请提升至1G),适配插件已实现资源的自动缓存与更新

# 工具转换

我们提供了Unity转换插件帮助开发者将项目自动导出为微信小游戏包,随后即可使用微信开发者工具或Android/iOS/PC真机进行预览。 下载 Unity插件, 并导入至游戏项目中。

# 平台能力接入

微信小游戏平台提供众多开放能力,但目前是以JavaScript API形式提供。 为了降低开发者进行平台能力对接的门槛,我们提供了平台能力C# SDK,因此依然可以熟悉的C#接口进行平台能力使用。相关文档

# 调优体验

转换工具能帮助开发者快速转换原有Unity项目,然而对于优质的小游戏我们还需要更多的体验调优以取得良好的上线表现。

关于调优请参考文档:

# 问题反馈与联系我们

# Cocos/Laya/Egret引擎适配

# 支持情况

许多开发者对小游戏对 Cocos、Egret、Laya等游戏引擎的支持情况非常关心。但是小游戏是一个不同于浏览器的 JavaScript 运行环境,没有 BOM 和 DOM API。然而,基本上所有基于 HTML5 的游戏引擎都是依赖浏览器提供的 BOM 和 DOM API 的。所以如果要在小游戏中使用引擎,需要对引擎进行改造。

目前,Cocos、Egret、Laya 已经完成了自身引擎及其工具对小游戏的适配和支持,对应的官方文档已经对接入小游戏开发做了介绍。

# 小游戏是一个不同于浏览器的运行环境

无论是怎样的引擎,最终在游戏运行时所做的大部分事情都是 随着用户的交互更新画面和播放声音。小游戏的开发语言是 JavaScript,那么在引擎的底层就需要通过 JavaScript 调用绘制 API 和音频 API。

一段 JavaScript 代码在运行时可以调用的 API 是依赖于 宿主环境 的。我们最常用的 console.log 甚至都不是 JavaScript 语言核心的一部分,而是浏览器这个宿主环境提供的。常见的宿主环境有浏览器、Node.js 等。浏览器有 BOM 和 DOM API,而 Node.js 则没有;Node.js 有 fs、net 等 Node.js 核心模块提供的文件、网络 API,而浏览器则不具备这些模块。例如,下面这段在浏览器中可以正常运行的代码,在 Node.js 中运行就会报错。

let canvas = document.createElement('canvas')

因为 Node.js 这个宿主环境根本没有提供 document 这个内置的全局变量。

ReferenceError: document is not defined

小游戏的运行环境是一个不同于浏览器的宿主环境,没有提供 BOM 和 DOM API,提供的是 wx API。通过 wx API,开发者可以调用 Native 提供的绘制、音视频、网络、文件等能力。

如果你想创建画布,你需要调用 wx.createCanvas()

let canvas = wx.createCanvas()
let context = canvas.getContext('2d')

如果你想创建一个音频对象,你需要调用 wx.createInnerAudioContext()

let audio = wx.createInnerAudioContext()
// src 地址仅作演示,并不真实存在
audio.src = 'bgm.mp3'
audio.play()

如果你想获取屏幕的宽高,你需要调用 wx.getSystemInfoSync()

let { screenWidth, screenHeight } = wx.getSystemInfoSync()

但是基于 HTML5 的游戏引擎会通过以下方式去创建画布、音频,获取屏幕宽高

let canvas = document.createElement('canvas')
let audio = document.createElement('audio')
console.log(window.innerWidth)
console.log(window.innerHeight)

此时会产生错误,理由如前文所述,小游戏这个宿主环境根本没有提供 document 和 window 这两个在浏览器中内置的全局变量。因为小游戏环境是一个不同于浏览器的宿主环境。

ReferenceError: document is not defined
ReferenceError: window is not defined

所以,基本上所有基于 HTML5 的游戏引擎都不能直接迁移到小游戏中使用,因为引擎可能或多或少都用到了 BOM 和 DOM 这些浏览器环境特有的 API。只有对引擎进行改造,将对 BOM 和 DOM API 的调用改成 wx API 的调用,引擎才能运行在小游戏环境中。

除了修改引擎,还有一种适配方式,即在引擎和游戏逻辑代码之间加一层模拟 BOM 和 DOM API 的适配层,我们称之为 Adapter。这层适配层在全局通过 wx API 模拟了引擎会访问到的那部分 window 和 document 对象的属性和方法,使引擎感受不到环境的差异。

Adapter 是用户代码,不是基础库的一部分。关于 Adapter 的介绍,参见教程 Adapter

# 使用其他游戏引擎

除去以上提到的兼容了小游戏平台的游戏引擎,开发者如果想用其他 HTML5 游戏引擎来开发小游戏也是可以的,但需要对其进行修改。修改思路建议为先引入通用的 Adapter 尝试运行,再把遇到的问题逐个解决。

粤ICP备19107308号