前言
游戏开发中,"热更"的重要性不言而喻。归根到底,他的原理只是一个"资源"重定向。
为什么"热更"带有引号呢?
游戏开发中常说的热更不是严格意义上的热更,仅仅只是在不用重装客户端的情况下,在游戏开始时替换某些资源,以达成所谓"热更"。
并非是在资源已经加载进游戏内存了,在运行时实时替换。
为什么需要热更呢?
不过即使不是严格意义上的热更,也带来了非常多的好处
- 不用重新安装客户端,就可以更改某些资源(这里代码也可以算做一种资源),大大的节省了用户安装的时间,更好的用户体验。
- 不用每次都重新全量打包,要验证某些问题时,只需要热更局部的资源,大大的节省了Debug的时间。
也存在一些缺点
- 可能需要使用一些嵌入式脚本语言,会导致程序性能降低
- 资源的重定向以及差异化,也带来了更大的开发难度
相较于它的优势,他带来的劣势足以让人忽略,热更目前已经是一款快速迭代游戏的标配了,因此了解其方案或思路是十分有必要的。
如何热更呢?
以下将lua代码和UE资源(uasset,umap等)热更分开来说明
Lua热更新(UnLua)
一开始就说到所谓热更,即资源的重定向,那就先来说说Lua热更加载的一个流程,如下图
可以看出非常的简单,需要确定游戏中自定义的沙盒路径,例如UE中的话主要就是Saved目录,然后require的时候先尝试去沙盒路径中去读取文件,如果能读取到就使用此路径下的文件,如果读取不到再使用原路径下的文件。
在此介绍两种热更的情况
本地(方便调试)
先说说本地热更的情况,这里其实最重要的一步就是确定热更加载的沙盒目录所在,将文件拷贝到沙盒目录下的相对路径即可。
在UnLua源码中,可以得知其默认的沙盒目录Saved下的PersistentDownloadDir下,如下图
确定沙盒路径的代码如下
远程
在实际生产环境中都是使用远程热更的方式,一个游戏发布出去,玩家每次登录游戏的时候会从相应版本的资源服务器拉取对应的差异资源文件,简要流程如下图所示
只需要在服务器上配置好对应版本的热更文件夹,每个版本对应文件夹去拉取
拉取下来后直接放在沙盒目录中,接下来的流程和本地情形保持一致。
相较于本地的情形,多了一步下载差异文件,仅此而已
资源热更新
资源相较于lua代码有些许差异,一般资源为了压缩会采用二进制的形式保存,在不考虑差量热更的情况,其实可以将lua代码也归结于资源的一种,资源的热更流程完全与上述lua代码热更保持一致。
只是在UE中资源的沙盒路径为: Saved/Paks目录下
并且要单个资源打包出也得使用引擎提供的相关命令行,而不能类似使用lua文件直接拷贝
热更小工具
热更流程已经清楚,但是要如何打包所需热更文件,上传(远程)或替换(本地)
在window右键菜单直接进行热更上传
安装与卸载
- WindowsContextMenuInstall.bat
这里注册的是TestUpdate的命令
@echo off
reg add "HKCR\*\shell\TestUpdate\command" /t REG_SZ /d "\"%~dp0TestUpdate.bat\" \"%%1\" " /f
pause
- WindowsContextMenuUninstall.bat
@echo off
reg delete "HKCR\*\shell\TestUpdate" /f
pause
- TestUpdate.bat
@echo off
if "%1" == "" goto :eof
set param1=%1
echo %param1%
pause
这里可以直接在bat里进行window相关的命令行开发
也可以使用python来做
上述双击执行完成WindowsContextMenuInstall.bat后
右键我们最后写的bat,点击HotFix或TestUpdate,就会出现黑窗口弹出这个文件的路径
示例
这里用示例来完成一次github上开源Unlua项目中Turorials/01_Helloworld中的Lua脚本热更
未热更执行结果
准备需要热更的lua代码
在Content/Script目录下
修改后
来到此文件的目录下执行所写的一个快速复制工具。
会发现其在沙盒目录下创建了这样一个相对路径。
热更后执行结果
再次运行游戏
已经是热更后的文件,此时无论如何修改Content/Script/Tutorials/01_HelloWorld.lua,此文本都不会有变化,只有当我们删除沙盒目录下的对应的热更文件,或者重新热更新的文件才会有变化。
热更复制工具代码
在工程目录下创建一个Tools文件夹
然后编写几个批处理文件用于快速到目录复制文件,此方法常用于本地热更测试,安卓会使用adb来完成文件的复制,这里只是举例说明windows端
- WindowsContextMenuInstall.bat
安装window命令到右键菜单
@echo off
reg add "HKCR\*\shell\HotFix\command" /t REG_SZ /d "\"%~dp0HotFix.bat\" \"%%1\" " /f
pause
- WindowsContextMenuUninstall.bat
卸载对应window命令
@echo off
reg delete "HKCR\*\shell\HotFix" /f
pause
- HotFix.bat
此次执行的window命令集
@echo off
if "%1" == "" goto :eof
set param1=%1
echo %param1%
python %~dp0MovePy.py %param1% %~dp0
pause
- MovePy. py
编写python文件进行文件夹的操作,主体逻辑使用python也便于多平台的移植。
import os
import sys
curFile = sys.argv[1]
toolPath = sys.argv[2]
sandDir = toolPath+ "..\\Saved\\PersistentDownloadDir"
print(os.path.abspath(sandDir))
if not os.path.exists(sandDir):
os.mkdir(sandDir)
contentList = curFile.split("\\")
tarDir = None
for item in contentList:
if item == 'Content':
tarDir = ""
if tarDir!=None:
tarDir += "\\" + item
tarDir = sandDir + tarDir
tarPath = os.path.dirname(tarDir)
print(tarPath)
if not os.path.exists(tarPath):
os.makedirs(tarPath)
cmd = "copy " + curFile + " " + tarPath
os.system(cmd)
# android使用adb工具
扩展,如果是远程热更,就将对应文件上传到资源服务器下对应版本文件夹中,供客户端下载。