虎牙小游戏 - Unity接入方案
介绍
本方案基于WebAssembly技术,无需更换Unity引擎将游戏项目适配到虎牙小游戏。
版本兼容性
Unity 虎牙小游戏适配方案是以 Unity Webgl 为基础,建议使用 Unity 2022,支持更多特性。
开发指南
1. 虎牙小游戏SDK安装
配置project.config.json,添加unitySDK参数,设置为true。
2. 虎牙小游戏SDK安装
使用 PackageManager 方式安装虎牙小游戏SDK。
- 打开游戏工程 -> Unity/团结引擎 Window 菜单栏 -> Package Manager -> 右上方 “+” -> Add package from git URL
3. Unity导出配置
添加对应的构建模板。
- 打开游戏工程 -> Unity/团结引擎 虎牙小游戏 菜单栏 -> 添加构建模板
- 虎牙小游戏构建模板导入项目中。
选择Webgl的导出模式。
- 打开游戏工程 -> Unity/团结引擎 File 菜单栏 -> Build Settings
- 选择WebGL平台进行构建。建议Scene In Build 仅勾选 Loading 场景,后续场景使用 AssetsBundle / Addressable 进行按需加载。
点击构建设置界面的Player Settings,选择虎牙小游戏构建模板。
在项目设置中设置Compression Format为Disabled,关闭导出的压缩格式。
4. 导入游戏
在游戏开发完成后, 把 Unity 游戏引擎的构建结果复制到 h5Dir 文件夹内.
后续调试、提测与发布流程,参照开发指南 。
Unity SDK 的使用
支持范围
本Unity SDK对HYSDK的支持与 API 文档大部分相同。 具体支持的 API 可以查看HY.cs文件,其中有详细注释说明。
调用方法
Unity 版本的 API 与 API 文档的 JS 版本 API 类似,使用时可以参考。
如 JS 版的 hy.getUserInfo的调用如下:
hy.getUserInfo({
success(res) {
console.log('用户昵称', res.userNick)
},
fail(res) {
console.log(res.errMsg)
}
})
而对于 Unity 版的调用如下:
HY.GetUserInfo(new GetUserInfoOption {
success = (userInfo) => {
Debug.Log("用户昵称: " + userInfo.userNick);
},
fail = (err) => {
Debug.LogError("GetUserInfo failed: " + err.errMsg);
}
});
Unity SDK 特供API
此处列出 API 文档 中未列出,仅在Unity SDK中可用的API列表。
| 类别 | 函数名 | 备注 |
|---|---|---|
| 基础功能 | CanIUse | 判断 API 在当前环境是否可用 |
| CallJSFunction | 调用 JS 函数 | |
| CallJSFunctionWithReturn | 调用 JS 函数并获取返回值 |
更新机制
在 PackageManager 选择HYSDK,点击Update进行更新。
网络通信适配
由于安全性的影响,JavaScript 代码没有直接访问 IP 套接字来实现网络连接。因此,该.NET 网络类(System.Net 命名空间中的一切,特别是System.Net.Sockets)在 WebGL 中不能工作。UnityEngine.Network* 类也是这样,编译 WebGL 时将找不到这些类。
HTTP 通信
Unity 支持在 WebGL 中使用 UnityWebRequest 类。
使用方式
以下为使用协程方式发送 GET、POST 请求到服务器的示例:
IEnumerator Get()
{
UnityWebRequest webRequest = UnityWebRequest.Get("https://website.com");
yield return webRequest.SendWebRequest();
if (webRequest.isHttpError||webRequest.isNetworkError)
{
Debug.Log(webRequest.error);
}
else
{
Debug.Log(webRequest.downloadHandler.text);
}
}
IEnumerator Post()
{
WWWForm form = new WWWForm();
//键值对
form.AddField("key", "value");
form.AddField("name","huya");
form.AddField("blog","huya123");
UnityWebRequest webRequest = UnityWebRequest.Post("https://website.com", form);
yield return webRequest.SendWebRequest();
if (webRequest.isHttpError||webRequest.isNetworkError)
{
Debug.Log(webRequest.error);
}
else
{
Debug.Log(webRequest.downloadHandler.text);
}
}
特别地,在 Unity WebGL 环境下禁止使用以下代码:
while(!www.isDone) {}
不能阻止线程等待 UnityWebRequest 下载完成,否则您的应用程序将冻结。因为 WebGL 采用单线程机制,并且由于 JavaScript 中的 网络 API 是异步的,所以除非您将控制权交回给浏览器,否则下载永远不会完成。取而代之的做法是使用协程和 yield 语句等待下载完成。
WebSocket
客户端
支持 Unity Websocket 的第三方插件比较多,可以从 Github 或 AssetStore 找到。这里以UnityWebSocket为例。
// 命名空间
using UnityWebSocket;
// 创建实例
string address = "ws://echo.websocket.org";
WebSocket socket = new WebSocket(address);
// 注册回调
socket.OnOpen += OnOpen;
socket.OnClose += OnClose;
socket.OnMessage += OnMessage;
socket.OnError += OnError;
// 连接
socket.ConnectAsync();
// 发送 string 类型数据
socket.SendAsync(str);
// 或者 发送 byte[] 类型数据(建议使用)
socket.SendAsync(bytes);
// 关闭连接
socket.CloseAsync();
服务端
如果服务端使用 TCP 接入,则需要使用 WSS<-->TCP 的代理层。解决方案也很多:
- 使用 Ngnix、 websockify-js/websockify做反向代理(推荐)
- 改造原有TCP服务兼容wss服务
特别地,在处理WebSocket数据包时,请注意数据的“粘包”问题,需要游戏服务器自行处理。