美文网首页征服Unity3dunity3D技术分享Unity跨平台技术分享
【Unity - xLua 热更新入门】从代码到发布的完整流程—

【Unity - xLua 热更新入门】从代码到发布的完整流程—

作者: 大刀和长剑 | 来源:发表于2019-03-19 18:45 被阅读0次

    本文的流程是这样:

    • 准备
    • 项目中导入xLua
    • 创建最简单的热更新框架
    • 开启服务器端的热更新服务
    • Unity中测试热更新
    • 发布到安卓手机上测试热更新
    • 结束
    • 下载

    在本文开始之前,将认为读者已掌握Unity的基本知识,比如创建项目啊,写脚本啊,什么的;也认为读者已掌握Lua的基本知识,比如Lua代码里创建个GameObject啊什么的,另外本文选择的热更方案是xLua,读者需要知道这点。

    服务器端我将用Go写个简单的服务器程序,用于客户端更新文件,这方面读者不用担心,在本文的最后提供了下载地址,并有简单的使用介绍,到时候下载后直接运行就行了。

    热更新很简单,简单的话就一句话:从远端获取需要热更新的资源,然后重新运行代码 —— 因为xLua等一些热更方案已经做的挺好了,我们需要做的其实只剩下去下载东西,然后运行它。

    本文在提到更新时将会写更新资源,而不是写更新lua代码,因为代码也是资源。

    本文也提供了这个测试项目下载链接,如果需要的话,可以去本文最后去下载查看。

    本文的测试环境:

    • macOS Mojave 10.14.2 / MacBook Pro 2015
    • Unity 2018.3.8f1
    • Lua:xLua

    准备

    准备工作主要准备以下的文件:

    一切准备好后,用Unity创建一个名为xlua-test的项目,就可以开始我们的热更新了。

    xlua-test项目已经准备好

    项目中导入xLua

    导入xLua非常简单:

    1. 解压 xLua-master
    2. 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等热更新方案把工作已经做完了,我们只需要去远端获取资源即可。

    这样就涉及两个问题:

    1. 客户端什么时候应该更新Lua代码或资源(热更新的时机)
    2. 去哪里更新

    作为测试,我们这里的答案也很简单:

    1. 如果有最新的资源,就立即更新,然后替换掉本地旧资源(或许根据需求决定的其他更新时机)
    2. 去服务器那里更新(本地搭建的服务器那里)

    所以我们的热更新逻辑是这样的:

    1. 每次打开客户端,都会向服务器发送本地资源的特征,询问是否需要更新
    2. 服务器收到客户端发来的询问,对比文件差异,如果需要更新,将返回需要更新的文件列表url
    3. 客户端如果收到服务器发来的文件更新列表url,将立即前往下载,并存储在本地;如果收到字符串"0",表示无需更新资源,则直接进入第4步。
    4. 开始运行客户端的主逻辑

    好啦,把刚才测试xLua是否能正常工作的代码删掉。

    我们开始完成客户端的相关代码,创建一个名叫UpdateController的C#脚本,(代码一百多行,就不贴出来了,就贴个图吧,想看细节可以去文章的最后去下载 xlua-test,很简单的代码。),我使用md5来简单计算文件的特征,server 程序也使用 md5 来进行文件对比:

    UpdateController

    然后再创建一个名叫MainController当做我们的主逻辑脚本(就贴个图吧,想看细节可以去文章的最后去下载 xlua-test,很简单的代码。):

    MainController

    把它们挂到对象上,客户端的工作已完成,如下:


    将更新脚本和主逻辑脚本挂在对象上,客户端工作已完成

    此时我们运行一下Unity,将得到一个本地资源存储的位置和一个不能连接host的提示,如果你也是如此,不用慌,则表明现在一切正常,可以进行下一步操作:


    得到一个本地资源存储的位置和一个不能链接host的提示,如果你也是如此,则表明现在一切正常,可以进行下一步操作...

    开启服务器端的热更新服务

    你可以去本文的最后下载 xlua-test-server,解压后打开查看,找到并运行适合你操作系统的服务器程序,比如说我的是macOS 64位的,我就打开终端,cd 到该目录下,然后 ./xlua_test_server__darwin_amd64

    macOS上运行 server 程序

    此时本地的服务器已经开启了。

    Unity 中测试热更新

    我们运行Unity 编辑器试试看结果:

    热更新已完成,程序运行正常。
    此时我们去看本地的资源目录,就会发现服务器上的资源已经被更新到本地了:
    服务器上的资源已经被更新到本地
    我们再次运行Unity 编辑器,发现客户端已经不再从服务器中下载文件了,因为本地的资源已经和服务器上的一模一样了,不必更新:
    再次运行Unity客户端程序,客户端已经不再从服务器中下载文件了
    我们去把服务器上的createObj/bg.lua.txt 文件修改下,使之再创建一个方块,并且修改一下方块的位置:
    把服务器上的`createObj/bg.lua.txt` 文件修改下,使之再创建一个方块,并且修改一下方块的位置
    再次运行Unity编辑器,看看有什么变化,此时只有一个文件需要下载,并且加载lua后,方块也出现了,一切合乎逻辑:
    再次运行Unity客户端程序,一切合乎逻辑。

    发布到安卓手机上测试热更新

    先别急着打包apk,首先把手机的网络设置要,具体来说就是手动设置代理(看你的手机品牌是怎么设置代理的,我写的可能不适合你的手机。)——wifi 的高级选项中把你的服务器ip地址(如果在本地运行的 server,你填自己的电脑的ip就好):

    如果在本地运行的 server,你填自己的电脑的ip
    端口是 12345,12345 如果你修改了 conf.txt 文件,则填你修改的端口,最后如下,保存,这时候 wifi 显示已连接表示手机配置成功(你的 server 要先打开啊!!! 端口跟你server开放的端口一致,所以你的server要先运行,不然手机上哪里链接啊,是吧,server 的端口介绍本文最后写的有:
    手机设置代理,保存,wifi 连接成功表示设置成功。
    ):

    好啦,现在我们将xlua-test项目打包成apk,安装到安卓手机上运行一下试试:

    apk 生成中 ...
    立即在手机上运行下这个客户端:
    看到一个球一个方块

    紫色? 这不是我们程序的问题,因为我们项目主逻辑就只是运行 lua 文件,而lua文件中创建的也只有Unity系统自带的模型,显而易见,Unity系统自带的模型材质在安卓平台上不适合了,所以这个 bug 不是我写的。

    我们此时在服务器中再次修改下程序,在左边再创建一个方块:

    在左边再创建一个方块

    重新运行手机上的客户端:


    一个球,两个方块。

    电脑上的服务器关掉,然后再此重新运行手机上的客户端,等了三四秒后(UpdateController 中写的超时时间,你可以修改),方块和小球又出现了:

    服务器关掉,然后再此重新运行手机上的客户端,等了三四秒后,方块和小球又出现了

    结束

    这个测试程序没有提示信息,Unity 编辑器里面运行还好,能看到输出,手机上就啥也看不到了,因为没有写界面。

    另外就是本文的程序只在安卓手机上测试通过了,iPhone上没有试过,因为我没有iPhone啊 。

    就这样了,xLua把主要功能已做的蛮完整的,剩下的就是去远端下载资源而已,xLua还有个热补丁本文中没有涉及到的。我只是把整个流程走通一遍,读者根据这个应该能够顺利的学习其他内容了。

    下载

    • 我们在文中创建的 xlua-test 项目,里面包含了 UpdateControllerMainController微云: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 的简单的用法

    1. 运行server之前,你还能看到一个conf.txt文件,打开它,里面就一行这个:
    port=12345
    

    意思是 server 开放的端口是12345,这样运行 server 之后,server 将在端口 12345 上监听消息,所以客户端里的 host 也应该使用 12345端口。

    如果运行后发生了端口占用(就是此端口已经被别的程序使用了),可以修改这个端口;如果你把 conf.txt 删掉了,server 将固定使用端口 12345 来给客户端提供更新服务:

    如果 server 以端口 12345 在本地运行,则客户端 Host 也需要设置为 "http://localhost:12345"
    1. 另外是服务器上的资源根目录是默认的resources

    意思是server运行目录下的 resources 文件夹,里面放的都是我们的需要热更新的资源,包括 lua 代码, 可以看到里面已经有了几个文件,你可以在这个目录下随意增删内容,它们将被更新到客户端中。

    1. 如果你把 server 的可执行文件复制另外的目录,然后想让它在该的目录下运行了。那么,如果你想更新资源或热更lua代码,则你需要在该目录下创建个 resources 文件夹,然后把你资源或lua代码放在里面。

    2. lua文件的保存格式为UTF8,切记。如果出现类似 ...main.lua.txt:1: unexpected symbol near '<\239>'...的报错信息,多半就是你的 lua 文件的编码格式的问题。

    相关文章

      网友评论

        本文标题:【Unity - xLua 热更新入门】从代码到发布的完整流程—

        本文链接:https://www.haomeiwen.com/subject/nigvmqtx.html