跳到主要内容

UnityWebGL 接入指南

说明

Unity WebGL 适配方案是以 WebAssembly 技术为基础,Unity 2021 之后的版本针对 WebGL 有大量的优化,如增加了对 ASTC 纹理压缩的支持、对音频的压缩等。所以我们仅推荐使用 2021 之后的版本,或中国特供版针对性优化的版本。并非每个小版本我们都有足够的验证,我们会根据实测情况以及开发者反馈的情况给出建议。

一、构建/发布

1.1 安装 Unity WebGL

如果安装了 Unity WebGL 平台,即能够切换到如下所示的平台(构建工具在构建时也会切换)

UnityWebGL平台

1.2 构建指南

具体构建参照 Unity 文档手册,以2021.2手册为例:构建和运行 WebGL 项目

注意事项

  1. WebGL 模板:建议选择 Default 或者自定义模板,不要选择 Minimal(会让玩家感觉有一段时间的白屏),例如:

    UnityWebGL-Default

  2. 发布设置:可参考以下示意图:

    UnityWebGL发布设置

1.3 补文件

在构建产物根目录,手动追加以下文件:

  • project.config.json
  • game.json

文件内容请参考官方文件说明

1.4 提交

使用 芒果开发者工具 直接导入该目录:

  1. 调试
  2. 预览
  3. 一键上传,完成上线

建议:使用真机进行测验,确保游戏在真实环境下运行正常。

二、包体优化注意事项

对上传平台的包体进行了大小限制,需注意以下四点:

2.1 分包

  • 推荐做法:将游戏资源进行AB分包,并将这些分包部署在 CDN 服务器上,进行远程加载AB包,不要进行本地加载。
  • 目的:减少初始包体大小,加快首次加载速度,提升用户转化率。

2.2 加载分包

以下是 Unity WebGL 加载远程 AssetBundle 的示例代码:

using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

public class RemoteABLoader : MonoBehaviour
{
public string abUrl = "http://yourserver.com/myabcube.unity3d"; // 远程AB包URL
public string assetName = "CubePrefab"; // 资源名称

void Start()
{
StartCoroutine(LoadAssetBundle());
}

IEnumerator LoadAssetBundle()
{
UnityWebRequest www = UnityWebRequestAssetBundle.GetAssetBundle(abUrl);
yield return www.SendWebRequest();

if (www.result != UnityWebRequest.Result.Success)
{
Debug.LogError("AB包加载失败: " + www.error);
yield break;
}

AssetBundle ab = DownloadHandlerAssetBundle.GetContent(www);
GameObject prefab = ab.LoadAsset<GameObject>(assetName);

if (prefab != null)
{
Instantiate(prefab, Vector3.zero, Quaternion.identity);
}
else
{
Debug.LogError("资源加载失败: " + assetName);
}
}
}

2.3 真机加载失败排查建议

  • 问题现象:分包在芒果开发者工具中能正常加载,但在真机上失败。
  • 常见原因:CDN 未正确配置跨域(CORS)。
  • 解决方案:检查并配置 CDN 的跨域设置,参考提供的《设置跨域指南》。

2.4 上传包体大小与转化率关系

  • 芒果开发者工具会将发布后目录中的所有内容打包上传。
  • 用户首次进入游戏需经历:下载包体 → 解压 → 启动游戏
  • 结论:包体越小,下载越快,转化率越高。
  • 建议:尽可能压缩资源、剔除冗余文件、使用远程分包等手段最小化上传包体体积。

三、接入平台接口

芒果小游戏平台提供的是 JavaScript 接口,需要按照 Unity WebGL 与浏览器 JavaScript 的双向通信方式进行接入,具体参考官方文档,以 2021.2 手册为例:WebGL:与浏览器脚本交互

3.1 从 Unity 脚本调用 JavaScript 函数

需要接入方编写 .jslib 中间件,在 .jslib 中调用平台的接口,以 isLogin 为例:

mergeInto(LibraryManager.library, {
isLogin: function (x, y) {
return window.mgtv.isLogin(); // 也可以使用 window['mgtv'].isLogin() 或 mgtv.isLogin()
},
});

然后在 C# 脚本中调用 .jslib 中的函数:

using UnityEngine;
using System.Runtime.InteropServices;

public class NewBehaviourScript : MonoBehaviour {

[DllImport("__Internal")]
private static extern bool isLogin();

void Start() {
bool isLogin = isLogin();
Debug.Log(isLogin);
}
}

3.2 从 JavaScript 调用 Unity 脚本函数

如果计划从嵌入页面的全局作用域调用内部 JavaScript 函数,则必须在构建 WebGL 后的 index.html 中使用 unityInstance 变量。在 Unity 引擎实例化成功后执行此操作:

var myGameInstance = null;
script.onload = () => {
createUnityInstance(canvas, config, (progress) => {
// 进度处理代码
})
.then((unityInstance) => {
myGameInstance = unityInstance;
// 其他初始化代码
}).catch((message) => {
// 错误处理代码
});
};

需要从 JavaScript 向 Unity 脚本发送数据或通知时,建议调用场景中游戏对象上的方法:

MyGameInstance.SendMessage(objectName, methodName, value);

其中:

  • objectName:场景中的对象名称
  • methodName:当前附加到该对象的脚本中的方法名称
  • value:可以是字符串、数字,也可为空

示例

MyGameInstance.SendMessage('MyGameObject', 'MyFunction');
MyGameInstance.SendMessage('MyGameObject', 'MyFunction', 5);
MyGameInstance.SendMessage('MyGameObject', 'MyFunction', 'MyString');

3.3 平台接口指南

四、调试

需要查看调试日志信息时,在发布后的 index.html 中加入以下代码:

<script type="text/javascript" src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
<script type="text/javascript">
new window.VConsole();
</script>

注意:正式发布版本时,需要隐藏相关调试设置。