本文的流程是这样:
- 准备
- 项目中导入xLua
- 创建最简单的热更新框架
- 开启服务器端的热更新服务
- Unity中测试热更新
- 发布到安卓手机上测试热更新
- 结束
- 下载
在本文开始之前,将认为读者已掌握Unity的基本知识,比如创建项目啊,写脚本啊,什么的;也认为读者已掌握Lua的基本知识,比如Lua代码里创建个GameObject啊什么的,另外本文选择的热更方案是xLua,读者需要知道这点。
服务器端我将用Go
写个简单的服务器程序,用于客户端更新文件,这方面读者不用担心,在本文的最后提供了下载地址,并有简单的使用介绍,到时候下载后直接运行就行了。
热更新很简单,简单的话就一句话:从远端获取需要热更新的资源,然后重新运行代码 —— 因为xLua等一些热更方案已经做的挺好了,我们需要做的其实只剩下去下载东西,然后运行它。
本文在提到更新时将会写更新资源,而不是写更新lua代码,因为代码也是资源。
本文也提供了这个测试项目下载链接,如果需要的话,可以去本文最后去下载查看。
本文的测试环境:
- macOS Mojave 10.14.2 / MacBook Pro 2015
- Unity 2018.3.8f1
- Lua:xLua
准备
准备工作主要准备以下的文件:
- 去 https://github.com/Tencent/xLua 下载
-
Android SDK(如果需要的话)
一切准备好后,用Unity创建一个名为xlua-test
的项目,就可以开始我们的热更新了。
项目中导入xLua
导入xLua非常简单:
- 解压
xLua-master
- 将
xLua-master/Assets
中所有内容复制到xlua-test/Assets
中
将 xLua-master/Assets 中所有内容复制到 xlua-test/Assets 中
复制后
Unity项目已导入xLua
创建个C#脚本迅速测试下刚导入的xLua是否能够正常工作:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MainController : MonoBehaviour
{
void Start()
{
XLua.LuaEnv luaenv = new XLua.LuaEnv();
luaenv.DoString("CS.UnityEngine.Debug.Log('hello world')");
luaenv.Dispose();
}
void Update()
{
}
}
运行,一切正常:
运行,一切正常
创建最简单的热更新框架
文章开头已经提到,热更新很简单,因为像xLua等热更新方案把工作已经做完了,我们只需要去远端获取资源即可。
这样就涉及两个问题:
- 客户端什么时候应该更新Lua代码或资源(热更新的时机)
- 去哪里更新
作为测试,我们这里的答案也很简单:
- 如果有最新的资源,就立即更新,然后替换掉本地旧资源(或许根据需求决定的其他更新时机)
- 去服务器那里更新(本地搭建的服务器那里)
所以我们的热更新逻辑是这样的:
- 每次打开客户端,都会向服务器发送本地资源的特征,询问是否需要更新
- 服务器收到客户端发来的询问,对比文件差异,如果需要更新,将返回需要更新的文件列表url
- 客户端如果收到服务器发来的文件更新列表url,将立即前往下载,并存储在本地;如果收到字符串
"0"
,表示无需更新资源,则直接进入第4步。- 开始运行客户端的主逻辑
好啦,把刚才测试xLua是否能正常工作的代码删掉。
我们开始完成客户端的相关代码,创建一个名叫UpdateController
的C#脚本,(代码一百多行,就不贴出来了,就贴个图吧,想看细节可以去文章的最后去下载 xlua-test
,很简单的代码。),我使用md5来简单计算文件的特征,server 程序也使用 md5 来进行文件对比:
然后再创建一个名叫MainController
当做我们的主逻辑脚本(就贴个图吧,想看细节可以去文章的最后去下载 xlua-test
,很简单的代码。):
把它们挂到对象上,客户端的工作已完成,如下:
将更新脚本和主逻辑脚本挂在对象上,客户端工作已完成
此时我们运行一下Unity,将得到一个本地资源存储的位置和一个不能连接host的提示,如果你也是如此,不用慌,则表明现在一切正常,可以进行下一步操作:
得到一个本地资源存储的位置和一个不能链接host的提示,如果你也是如此,则表明现在一切正常,可以进行下一步操作...
开启服务器端的热更新服务
你可以去本文的最后下载 xlua-test-server
,解压后打开查看,找到并运行适合你操作系统的服务器程序,比如说我的是macOS 64位的,我就打开终端,cd
到该目录下,然后 ./xlua_test_server__darwin_amd64
:
此时本地的服务器已经开启了。
Unity 中测试热更新
我们运行Unity 编辑器试试看结果:
此时我们去看本地的资源目录,就会发现服务器上的资源已经被更新到本地了:
服务器上的资源已经被更新到本地
我们再次运行Unity 编辑器,发现客户端已经不再从服务器中下载文件了,因为本地的资源已经和服务器上的一模一样了,不必更新:
再次运行Unity客户端程序,客户端已经不再从服务器中下载文件了
我们去把服务器上的
createObj/bg.lua.txt
文件修改下,使之再创建一个方块,并且修改一下方块的位置:把服务器上的`createObj/bg.lua.txt` 文件修改下,使之再创建一个方块,并且修改一下方块的位置
再次运行Unity编辑器,看看有什么变化,此时只有一个文件需要下载,并且加载lua后,方块也出现了,一切合乎逻辑:
再次运行Unity客户端程序,一切合乎逻辑。
发布到安卓手机上测试热更新
先别急着打包apk,首先把手机的网络设置要,具体来说就是手动设置代理(看你的手机品牌是怎么设置代理的,我写的可能不适合你的手机。)——wifi
的高级选项中把你的服务器ip地址(如果在本地运行的 server,你填自己的电脑的ip就好):
端口是
12345
,12345 如果你修改了 conf.txt
文件,则填你修改的端口,最后如下,保存,这时候 wifi
显示已连接表示手机配置成功(你的 server 要先打开啊!!! 端口跟你server开放的端口一致,所以你的server要先运行,不然手机上哪里链接啊,是吧,server 的端口介绍本文最后写的有:手机设置代理,保存,wifi 连接成功表示设置成功。
):
好啦,现在我们将xlua-test
项目打包成apk,安装到安卓手机上运行一下试试:
立即在手机上运行下这个客户端:
看到一个球一个方块
紫色? 这不是我们程序的问题,因为我们项目主逻辑就只是运行 lua 文件,而lua文件中创建的也只有Unity系统自带的模型,显而易见,Unity系统自带的模型材质在安卓平台上不适合了,所以这个 bug 不是我写的。
我们此时在服务器中再次修改下程序,在左边再创建一个方块:
在左边再创建一个方块重新运行手机上的客户端:
一个球,两个方块。
电脑上的服务器关掉,然后再此重新运行手机上的客户端,等了三四秒后(UpdateController
中写的超时时间,你可以修改),方块和小球又出现了:
结束
这个测试程序没有提示信息,Unity 编辑器里面运行还好,能看到输出,手机上就啥也看不到了,因为没有写界面。
另外就是本文的程序只在安卓手机上测试通过了,iPhone上没有试过,因为我没有iPhone啊 。
就这样了,xLua把主要功能已做的蛮完整的,剩下的就是去远端下载资源而已,xLua还有个热补丁本文中没有涉及到的。我只是把整个流程走通一遍,读者根据这个应该能够顺利的学习其他内容了。
下载
- 我们在文中创建的
xlua-test
项目,里面包含了UpdateController
和MainController
: 微云:xlua-test
xlua-test
- 我们要使用的服务器程序里面也包含
Linux、darwin、freebsd、windows
平台的可执行程序: 微云:xlua-test-server
xlua-test-server如果程序无法运行,里面的
main.go
文件就是整个server的源代码,可以自行安装Go,然后编译运行它即可。如果你Go已装好,并且使用
点击`终端/运行任务...`VSCode
打开了文件夹xlua–test–server
,则你只需要点击终端/运行任务...
,然后再弹出的窗上点run
,就可以运行server
然后再弹出的窗上点`run`,就可以运行server
macOS 允许它就 server 就可以了或许你会好奇,
run
下面的build all platform
是干嘛用的,它就是用来生成所有平台可执行程序的任务。server 的简单的用法
- 运行server之前,你还能看到一个
conf.txt
文件,打开它,里面就一行这个:port=12345
意思是 server 开放的端口是
12345
,这样运行 server 之后,server 将在端口12345
上监听消息,所以客户端里的host
也应该使用12345
端口。如果运行后发生了端口占用(就是此端口已经被别的程序使用了),可以修改这个端口;如果你把
如果 server 以端口 12345 在本地运行,则客户端 Host 也需要设置为 "http://localhost:12345"conf.txt
删掉了,server 将固定使用端口12345
来给客户端提供更新服务:
- 另外是服务器上的资源根目录是默认的
resources
。意思是server运行目录下的 resources 文件夹,里面放的都是我们的需要热更新的资源,包括 lua 代码, 可以看到里面已经有了几个文件,你可以在这个目录下随意增删内容,它们将被更新到客户端中。
如果你把 server 的可执行文件复制另外的目录,然后想让它在该的目录下运行了。那么,如果你想更新资源或热更lua代码,则你需要在该目录下创建个
resources
文件夹,然后把你资源或lua代码放在里面。lua文件的保存格式为UTF8,切记。如果出现类似
...main.lua.txt:1: unexpected symbol near '<\239>'...
的报错信息,多半就是你的 lua 文件的编码格式的问题。
网友评论