Unity SDK 正确的集成方法
文章目录
更新
- 2021/03/06 增加 JSON-RPC 2.0 规范推荐
- 2020/01/05 初次发布
介绍
Unity 游戏经常需要接入各种 SDK 实现支付、登录、分享等功能,但是很多项目使用了在 C# 中增加 SDK 接口的方法导致接入不同渠道 SDK 时需要反复打包,非常耗费时间。
前提
使用 Lua 编写逻辑的 Unity 项目。
需求
接入 SDK 时会使用 C# 编写游戏逻辑与 SDK 之间的接口,因此每增加一个新的 SDK 都需要新增对应的 C# 接口,最终导致打不同版本的 SDK 包必须使用 Unity 输出不同的工程。
这极大地浪费时间,打包耗时也随着 SDK 数量的增多而直线上升。如何降低时间呢?从现状分析可以发现耗时最大的部分是 Unity 生成工程,因此降低时间最直接的就是减少反复生成不同版本 Unity 工程耗费的时间。
速度最快的代码是不运行的代码,因为耗时为 0。由此可以推断出最好是只生成一次工程,去掉所有不必要的重复导出工程过程,不同的 SDK 共用一份生成的工程打包。
机制
需求是使用 Unity 生成一份工程后接入许多不同的 SDK,从而节省 Unity 打包时间。
由于 Unity 生成的工程不常变化,而游戏逻辑与 SDK 经常变化(接入不同 SDK、SDK 版本更新)。可以将代码简单地分为 C# 代码(Unity 工程内的代码)与非 C# 代码(Unity 生成的工程代码,包括 Java、Objective-C、Lua 等等),然后分别放到不同的工程内进行打包。
但是游戏逻辑需要与 SDK 之间进行通信,如何实现呢?通信的本质实际是 Remote procedure call - Wikipedia,这个就是平时客户端与服务器通信时使用的机制。而客户端与服务器之间是通过 socket 连接,类似地,游戏逻辑与 SDK 之间也需要这样的通道。
实现
通道
游戏逻辑只能通过 Unity 的 C# 与 SDK 进行通信。不同的 SDK 有不同的接口,且 SDK 升级后接口也会发生改变,因此需要将变化的部分从 C# 中移动到 SDK 中,C# 只提供基本的通道功能。
异步
C# 定义接口可以参考 RPC,即要实现调用与返回两个接口,因为调用本身可能是异步的,例如一部分 SDK API 是网络请求。
协议
协议内容可以尝试使用 JSON,因为 JSON 在各大平台上几乎都是内置支持的。当然这里正确的做法是使用 IDL 生成,例如 Protocol Buffers | Google Developers,考虑到 SDK 接口与内容并不复杂,可以手动维护两边的数据结构。
- 需要提供向前兼容性,即可以随意新增参数,可以适配 SDK 的新版本。
- 需要提供向后兼容性,这里的后是指的其他 SDK,因为一个 SDK 接口变化后需要不影响其他 SDK 接口。
这里推荐使用现成的 JSON-RPC 规范:
规范已经规定了版本号、方法名、参数、ID 之类的名字,使用规范有助于减少命名冲突。参数建议使用键值对的字典形式,有助于后续增加参数或调整参数顺序。
注意:为了兼容性,尽量不要删除参数,只管新增参数就可以维持最大的兼容性。
代码
以下代码只是给出一个范例,考虑到接收回调必须使用 MonoBehaviour 定义接收回调方法,由于这只是一个简单的演示代码,因此将其做成一个单例。
|
|
在定义完 C# 通道后,游戏逻辑使用 Lua 代码编写,SDK 根据平台使用对应的 Java 或 Objective-C 之类的代码编写,可以根据 method 名字派发到不同的方法中。
建议
Mockup 摸拟对象
单元测试中存在 Mockup 摸拟对象这个概念,用于替代真实对象的行为,在这里可以借用这个概念来实现以下 SDK:
- 可以考虑为 Unity 编辑器做一个单独的编辑器版本 SDK,可以用于在编辑器中模拟 SDK 的行为,这样调试起来比较方便。
- 另外也建议准备一份空版本 SDK,类似编辑器版本 SDK,只不过是用于真机上不接任何 SDK 时使用,这是模仿 Unity 命令行打包时使用的 NULL Graphics Device。
工程建议
- SDK 需要将 Demo 与文档作为产物放在 Release 仓库中,与原始仓库分离。
- 文档建议生成 PDF,可以包含图片,考虑使用 Markdown、Asciidoc 之类的标记语言,这样文档的格式是统一的,而不会出现到处是花花绿绿的颜色与格式。
- C# 中尽可能不使用宏定义,而是使用平台判断 API。可以防止宏定义导致的代码引用查找不全,静态分析遗漏宏定义中的代码。
文章作者 狂飙
初次发布 2020-01-05 22:58:10 +0800
上次更新 2021-03-06 23:18:52 +0800