Unity3D热更新之LuaFramework篇[09]--资源热更新与代码热更新的具体实现
前言
在上一篇文章 Unity3D热更新之LuaFramework篇[08]--热更新原理及热更服务器搭建 中,我介绍了热更新的基本原理,并且着手搭建一台服务器。
本篇就做一个实战练习,真正的来实现热更新功能。
一、准备工作
1、制作一个用于热更新的界面
此前我制作了一个大厅界面,并且放置了两个按钮:”排行榜“和”商城“,排行榜按钮已经用于打开排行榜页面。
所以,现在再制作一个商店页面,当点击商城按钮的时候,打开商店页面。
1) 制作ShopPanel界面。
a) 制作一个商店界面ShopPanel,界面上放一个标题和简单的3个商品项。如下图:
b)将ShopPanel做成预制体,放在Assets\LuaFramework\CustomPrj\Shop目录下。
c)创建ShopPalel.lua和ShopCtrl.lua并做CtrlNames注册和PanelNames注册。ShopPanel.lua放在Assets\LuaFramework\Lua\View\Shop目录下,ShopCtrl.lua放在Assets\LuaFramework\Lua\Controller\Shop目录下。
d)在Packager.cs的HandleExampleBundle方法中添加打包ShopPanel的代码;
//打包准备测试用的ShopPanel预制体
AddBuildMap("shop" + AppConst.ExtName, "*.prefab", "Assets/LuaFramework/CustomPrj/Shop");2) 点击商城按钮显示商店面板
a) 在HallPanel.lua中添加对商城按钮的引用;
local transform;
local gameObject; HallPanel = {};
local this = HallPanel; --启动事件--
function HallPanel.Awake(obj)
gameObject = obj;
transform = obj.transform; this.InitPanel();
logWarn("Awake lua--->>"..gameObject.name);
end --初始化面板--
function HallPanel.InitPanel()
logWarn("我是HallPanel,我被加载了."); --排行榜按钮
HallPanel.rankingBtn = transform:FindChild("BtnRanking").gameObject; --排行榜面板
HallPanel.rankingPanel = transform.parent:Find("RankingPanel"); --商店按钮
HallPanel.shopBtn = transform:FindChild("BtnShop").gameObject; --调用Ctrl中panel创建完成时的方法
HallCtrl.OnCreate(gameObject);
end function HallPanel.OnDestroy()
logWarn("OnDestroy---->>>");
endHallPanel.lua
b) 在HallCtrl.lua中添加商城按钮的事件处理
HallCtrl = {};
local this = HallCtrl; local behaviour;
local transform;
local gameObject; --构建函数--
function HallCtrl.New()
logWarn("HallCtrl.New--->>");
return this;
end function HallCtrl.Awake()
logWarn("HallCtrl.Awake--->>"); logWarn("我是HallCtrl,我被加载了.");
end --启动事件--
function HallCtrl.OnCreate(obj)
gameObject = obj;
transform = obj.transform; UIEventEx.AddButtonClick(HallPanel.rankingBtn, function ()
log("你点击了排行榜按钮"); HallPanel.rankingPanel.gameObject:SetActive (true);
end); UIEventEx.AddButtonClick(HallPanel.shopBtn, function ()
log("你点击了商店按钮"); --实例化商店面板
local shopCtrl = CtrlManager.GetCtrl(CtrlNames.Shop);
shopCtrl:Awake();
end);
end --单击事件--
function HallCtrl.OnClick(go)
destroy(gameObject);
end --关闭事件--
function HallCtrl.Close()
panelMgr:ClosePanel(CtrlNames.Hall);
endHallCtrl.lua
3) 打包并运行
a) 执行Build Windows Resources操作,新添加的ShopPanel会被自动打进包里
b) 运行Unity,点击“商城“按钮,正确地打开了商店面板。
2、修改热更配置
打开AppConst.cs脚本,
将UpdateMode设置为true;
将WebUrl的地址设置为http://192.168.0.110:8080/StreamingAssets/
这个192.168.110是我本机的ip,8080是Tomcat的默认端口号,这里根据实际情况修改为自己的ip即可。
修改位置见下图:
3、测试热更服务器
1)将Assets下的StreamingAssets目录整个复制到Tomcat下的webapps目录,我这里是
I:\apache-tomcat-9.0.22\webapps。
2)在浏览器中输入http://192.168.0.110:8080/StreamingAssets/files.txt 。
如果能获取到files.txt的内容,则表明热更服务器已经就绪。
二、资源热更新
1、制作一个客户端程序
热更新涉及两个操作方,一个是服务器,一个是客户端。服务器已经就绪了,现在还缺少一个客户端程序。
1)首先将unity工程转换到Android平台,点击Build Android Resource菜单重新生成打包资源。
2)待build完成后,将现在的项目打成一个apk包(注意将Hall场景放在0位置,以便首先加载这个场景)
(打包的时候如果出现报错说插件冲突和架构重复啥的,删掉Plugins目录下的x86目录就好,保留x86_64目录)
3)把StreamingAssets目录复制到Tomcat的webapps目录(之前的删掉就行)。之前测试服务器的时候拷过去的是Windows版本资源,无法和安卓客户端进行更新,所以这里需要重新拷贝。
4)安装这个apk包到手机,手机应该和电脑位于同一局域网。我这里使用的是一个安装在本机上的安卓模拟器。
5)运行刚安装的程序。
能正常打开大厅场景,点击商城按钮,也能正常弹出商店界面。如下图:
如果刚进游戏如果直接点击不起作用,等一下再试(正在解压资源)。
现在客户端也已经就绪。
2、制作更新内容并上传到热更服务器;
上一步的操作中,我们打了一个安卓包,并将此时的StreamingAssets目录复制了到了Tomcat中,现在的状态是:
服务器上的StreamingAssets内容和安卓客户的StreamingAssets内容是相同的。这种状态下客户端是不会进行更新操作的。
假使安卓包已经上线,过了几天,我们需要更新版本。
更新内容就是:调整商店页面的商品,将商品1进行更新。
现在制作一个新的商店页面。
1)修改ShopPanel的预制体,将原商品1的名称修改为“新品“,图标也进行调整,如下图:
2)执行Build Android Resource菜单,重新进行打包;
3)打包完成后,将StreamingAssets目录复制到Tomcat的webapps目录下,覆盖掉之前的内容。
3、重新运行客户端
经过上一步的操作,现在的服务器资源是更新后的显示为“新品”的资源,而客户而还是之前的显示为“商品1”的资源。如下图:
在商店资源更新到服务器后,不用重新打安卓包。
直接重新运行之前的安卓客户端 ,如果客户端打开商店显示了“新口”的商品,则说明资源热更新成功了(预制体是一种Unity资源)。
好了,重新运行客户端。
点击商城按钮。能看到,商店界面已经自动更新到服务器的版本了。
效果与预期的一致,资源热更成功。
三、代码热更新
这里说的代码热更,只包含lua代码,所有的c#代码是没法更新的。
所以c#代码一般用来写一此底层逻辑,以及通用型逻辑,具体的业务逻辑最好都由lua来实现。
在版本计划中,如果不得不改动c#代码,那就只能发个全量包了。
现在开始做代码热更。
计划:修改ShopPanel.lua的代码,在代码中动态修改商店界面的标题,如果能看到商店标题被更改,则表示代码热更成功。
1、 修改ShopPanel.lua的代码,在代码中引用标题所在的Text组件,并将商店标题修改为“热更商店”。具体修改见下图:
2、 点击Build Android Resource,重新生成打包资源;
3、 将StreamingAssets目录复制到Tomcat的webapps目录,覆盖掉之前的;
4、 重新运行客户端程序。
能看到商店的标题已经被修改了。
说明代码更新成功。
至此,热更操作实战演练完成。
一些说明:
- 本文选用安卓包做客户端,一是为了验证这个热更功能在移动端上的可用性;二是因为,这个资源热更功能在Windows平台无法正常加载更新的资源。可能是框架原因,也可能是我的疏漏,没有查证。 不过好在安卓平台上的热更是没有问题的。至于iOS平台,条件有限,没法去测试。
- 热更版本的包在第一次启动的时候,有一个漫长的解压缩过程,上一篇讲原理的时候,有提到过。直接表现就是第一次运行,会黑屏很久。我这里没有黑屏,是因为我的大厅面板是直接显示的,不用等待解压过程。 但是,一看到大厅界面,就立即点击排行榜按钮和商城按钮,是不会在响应的,因为资源未解压完成,lua脚本啥的还未加载。 我给工程加了一个Unity-Logs-Viewer插件,在屏幕上划2圈,能打开日志界面,从日志里能看到解压缩的过程。
- 关于更新,目前框架实现的逻辑也比较简单,直接比较files.txt的内容,发现不一致就进行更新。 如果是实际项目的话,要做版本控制:Tomcat的webapps目录下应该是按版本放置的资源,并提供服务端版本号,客户端要有取服务端版本信息的能力,并根据版本号,从不同的目录读取资源。
- 关于下载,目前的下载逻辑也比较简易,是按资源一定能下载成功做的逻辑,没有处理资源下载失败等异常情况,最好在UI上也能对此过程有显示,这个需要自己完善。
- 总的来说,这是一个可用的框架,但是还需要自己完善。
项目地址
为方便参照学习,本项目源码已经上传到github,地址:
Unity3D热更新之LuaFramework篇[09]--资源热更新与代码热更新的具体实现的更多相关文章
- Unity3D热更新之LuaFramework篇[10]--总结篇
背景 19年年初的时候,进到一家新单位,公司正准备将现有的游戏做成支持热更的版本.于是寻找热更方案的任务就落在了我头上. 经过搜索了解,能做Unity热更的方案是有好几种,但是要么不够成熟,要么不支持 ...
- Unity3D热更新之LuaFramework篇[03]--prefab加载和Button事件
在上一篇文章 Unity3D热更新之LuaFramework篇[02]--用Lua创建自己的面板 中,我介绍了LuaFramework加载面板的方法,但这个方法并不适用于其它Prefab资源,在这套框 ...
- Unity3D热更新之LuaFramework篇[02]--用Lua创建自己的面板
在上篇文章 Unity3D热更新之LuaFramework篇[01]--从零开始 中,我们了解了怎么获得一个可用的LuaFramework框架. 本篇将我会先介绍一下如何配置Lua开发环境,然后分析在 ...
- Unity3D热更新之LuaFramework篇[07]--怎么让unity对象绑定Lua脚本
前言 在上一篇文章 Unity3D热更新之LuaFramework篇[06]--Lua中是怎么实现脚本生命周期的 中,我分析了由LuaBehaviour来实现lua脚本生命周期的方法. 但在实际使用中 ...
- Unity3D热更新之LuaFramework篇[05]--Lua脚本调用c#以及如何在Lua中使用Dotween
在上一篇文章 Unity3D热更新之LuaFramework篇[04]--自定义UI监听方法 中,我对LuaBehaviour脚本进行了扩展,添加了两个新的UI监听方法,也提到最好能单写一个脚本处理此 ...
- Unity3D热更新之LuaFramework篇[04]--自定义UI监听方法
时隔一个多月我又回来啦! 坚持真的是很难的一件事,其它事情稍忙,就很容易说服自己把写博客的计划给推迟了. 好在终于克服了自己的惰性,今天又开始了. 本篇继续我的Luaframework学习之路. 一. ...
- Unity3D热更新之LuaFramework篇[08]--热更新原理及热更服务器搭建
前言 前面铺垫了这么久,终于要开始写热更新了. Unity游戏热更新包含两个方面,一个是资源的更新,一个是脚本的更新. 资源更新是Unity本来就支持的,在各大平台也都能用.而脚本的热更新在iOS平台 ...
- Unity3D热更新之LuaFramework篇[01]--从零开始
前言 因工作关系,需要对手头的项目进行热更新支持.了解后发现,Lua的几个变种:XLua.ToLua(原uLua)和Slua都可以做Unity热更,而ToLua更是提供了一个简易的热更框架--LuaF ...
- Unity3D热更新之LuaFramework篇[06]--Lua中是怎么实现脚本生命周期的
前言 用c#开发的时候,新建的脚本都默认继承自Monobehaviour, 因此脚本才有了自己的生命周期函数,如Awake,Start, Update, OnDestroy等. 在相应的方法中实现游戏 ...
随机推荐
- 利用Settings.bundle切换网络环境
目的:一次性打包,测试可以去iPhone设置,找到APP,点击后然后可以自主切换网络环境(测试.预生产.正式).关闭APP重新打开生效. 撸起袖子加油干…… 1.生成并设置Setting.bundle ...
- HBase —— 单机环境搭建
一.安装前置条件说明 1.1 JDK版本说明 HBase 需要依赖JDK环境,同时HBase 2.0+ 以上版本不再支持JDK 1.7 ,需要安装JDK 1.8+ .JDK 安装方式见本仓库: Lin ...
- 面试超火题 This的问题!!!
this问题 (1)this是js的一个关键字,指定一个对象,然后替代this: 函数中的this指向行为发生的主体,函数外的this都指向window,没有意义 (2)函数内的this跟函数在什么环 ...
- CSS清除默认样式代码
html, body, div, ul, li, h1, h2, h3, h4, h5, h6, p, dl, dt, dd, ol, form, input, textarea, th, td, s ...
- 漫谈Redis分布式锁实现
在Redis上,可以通过对key值的独占来实现分布式锁,表面上看,Redis可以简单快捷通过set key这一独占的方式来实现分布式锁,也有许多重复性轮子,但实际情况并非如此.总得来说,Redis实现 ...
- 使用SSH+SFTP操作终端全解析,告别XShell
1.前言 在Windows系统下操作远程服务器的方式很多,比如XShell+XFTP组合,亦或是PuTTY+WinSCP组合,但在Mac系统下登陆远程服务器,并没有这些工具供我们使用.相比较而言,在M ...
- JDK1.8集合之HashMap
目录 简介 内部实现 类的属性 Node数组 重要方法 put()和putVal()方法 get()和getNode()方法 resize()方法 容量设置为2的幂的优点 计算Hash时候 扩容时候 ...
- CSU 1808:地铁(Dijkstra)
http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1808 题意:…… 思路:和之前的天梯赛的一题一样,但是简单点. 没办法直接用点去算.把边看成点 ...
- C语言学习书籍推荐《学习使用C指针(影印版)(英文本)》下载
<学习使用C指针(影印版)(英文本)>作者通过<学习使用C指针(影印版)(英文本)>中的内存模型为你展示了如何在数组.字符串.结构和函数中使用指针.虽然难以掌握,但是指针为C语 ...
- Spark 的 python 编程环境
Spark 可以独立安装使用,也可以和 Hadoop 一起安装使用.在安装 Spark 之前,首先确保你的电脑上已经安装了 Java 8 或者更高的版本. Spark 安装 访问Spark 下载页面, ...








