议程
什么是热更新
为什么要热更新
如何在 iOS 上热更新 Unity 应用
支持Unity iOS热更新的各种Lua插件对比
什么是热更新
广义定义
无需停机手游热更软件源码,无需关闭服务器、修补漏洞、更新资源等。 重点是更新逻辑代码。
狭义定义(iOS热更新)
无需重新打包代码提交到AppStore来更新客户端的执行代码,即无需下载App并手动更新程序。
现状
苹果严格禁止C#的一些反射操作,禁止JIT(即时编译,程序运行时创建并运行新代码),不允许逻辑热更新,只允许使用AssetBundle进行资源热更新。
为什么要热更新
缩短用户获取新版本应用客户端的流程,提升用户体验。
具体到iOS平台的应用,有以下几个原因:
App Store的初始审核周期很难控制。
移动应用程序经常更新。
对于小型应用程序来说,更新成本太高。
最终状态
完全转换应用程序的内容,无需重新下载或停机。
如何在 iOS 上热更新 Unity 应用
Android应用程序热更新
将执行代码预编译到 assemblydll 中。
将代码作为 TextAsset 打包到 Assetbundle 中。
在运行时,利用Reflection机制来实现代码的功能。
通过更新对应的Assetbundle即可实现热更新。
Android和iOS热更新的异同
苹果正式禁止iOS下程序热更新; JIT在iOS下无效。
热更新方案:Unity+Lua插件。
使用Lua插件进行iOS热更新的原理
Unity热更新注意事项
需要更新的代码和资源必须打包成AssetBundle(建议使用未压缩的格式进行打包)
熟悉Unity的几条重要路径
资源(只读)
StreamingAssets(只读)
Application.dataPath(只读)
Application.persistentDataPath(可读可写)
重要路径资源
Resources文件夹下的资源无论使用与否都会被打包
资源将被压缩并转换为二进制
打包文件夹下的资源是只读的
无法动态修改,无法热更新
使用 Resources.Load 加载
StreamingAssets的重要路径
流数据的缓存目录
文件夹下的资源无论使用与否都会被打包
资源未压缩和加密
打包文件夹下的资源是只读的,主要存放二进制文件
无法热更新
WWW类加载(一般使用CreateFromFile,如果资源是AssetBundle,则要看是否按照其打包形式进行压缩)
相对路径,具体路径根据实际平台而定
Application.streamingAssetsPath
IOS:Application.dataPath +“/Raw”或Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data/Raw
重要路径Application.dataPath
游戏数据文件夹的路径(例如编辑器中的资产)
几乎没有使用过
无法热更新
IOS路径:Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data
重要路径Application.persistentDataPath
持久化数据存储目录的路径(沙箱目录,打包前不存在)
文件夹中的资源无论使用与否都会被打包。
运行时有效,可读可写
无内容限制,从 StreamingAsset 读取二进制文件或从 AssetBundle 读取文件写入 PersistentDataPath
适合热更新
IOS路径:Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Documents
使用Lua插件进行iOS热更新的整体流程
支持Unity iOS热更新的各种Lua插件对比
uLua(资产商店)
原生版uLua插件手游热更软件源码,鼻祖
不会形成静态代码
反射机制,效率低,速度慢,gcalloc频繁
已停止更新维护,不支持Unity5.x,已淡出主流。
乌鲁阿和cstoLua
开发平台成熟稳定,bug可快速修复
开发者众多,资源丰富
静态模式,性能优异
有成功的商业产品案例(爸爸三国、混沌战队、库尤巴钓鱼、绝地战警、这不是DOTA等)
两者都是在原生版本基础上的改进; 将来两者会合并成一个插件
sLua
静态模式,性能优异
简单的核心代码
资源少,开发平台不够成熟稳定
没有成功的商业产品案例 成功的商业产品案例
基于原生版本的改进
支持Unity iOS热更新的各种Lua插件对比
C#光(L#)
淡出主流
尤尼卢阿
C#实现的Lua虚拟机,非完整解决方案
淡出主流
支持Unity iOS热更新的各种Lua插件对比
然后是uLua和sLua的测试代码。
总体来说,uLua 肯定更好。
我不会谈论测试结果。 您可以下载 PDF 并亲自查看。