Lua教程 http://www.runoob.com/lua/lua-tutorial.html
下载uLua的SimpleFramework_UGUI_v0.4.1框架 http://www.ulua.org/
热更新流程
原理:使用assetbundle进行资源的更新,而lua运行时才编译的特性,所以.lua文件也可以被看成是一种资源文件(与文本,图片音频一个性质).在uLua新版的ToLua框架中.lua文件也被打包在ab里面了,这边使用的SimpleFramework是分开的.
流程:
1.对比files清单文件
2.更新文件
3.解AB包中的资源
4.初始化
游戏运行时从服务器下载files.txt清单文件,与本地的files.txt清单文件进行对比.如果新下载的files里面的md5值与本地files的md5值不一样,或者本地清单里根本没有这个文件就从服务器下载这个ab包到StreamAssets文件夹中.下载完毕后解开AB包中的资源,然后完成初始化.
工程目录:
Lua文件夹中写我们的Lua逻辑代码
StreamingAssets中存放打包的资源
uLua是核心文件
流程:
1.场景试图中只挂了1个GlobalGenerator脚本用来初始化,AppFacade是PureMVC的门面,然后发送StartUp的消息来启动PureMVC,在StatUpCommand.cs这个脚本中初始化了一堆管理器添加到场景中的GameManager这个物体上(PureMVC可阅读PureMVC最佳实践.pdf )
2.接着到GameManager.cs中,对比files清单文件,解包,下载等代码都在这边.比如对比清单文件再下载需要更新的资源.最后游戏的初始化就完成了.
详细介绍
步骤一:
1.我们下载的SimpleFramework_UGUI文件夹,将Assets里面的内容拷贝到新创建的Unity5工程中,将LuaEncorder拷贝到与Assets同级的目录下.

2.选择菜单Lua->单击Gen Lua Wrap Files 转换供Lua调用的C#文件(当我们供Lua调用的C#方法发生变化,就需要Gen Lua Wrap Files一次,清除则是使用下面的Clear LuaBindr file + Wrap files)

3.选择菜单Game->单机Build Windows Resources生成StreamAssets文件夹下的资源(需对应平台)

4.运行Example下的login例子 解包后出现以下画面,同时在C盘下生成simpleframework文件夹.

步骤二:
1.将示例场景中的GlobalGenerator和GuiCamera拖成Prefab,新建自己的场景,将这2个放入场景. (其中GuiCamera上有GuiCamera标签,uLua的框架就是根据这个标签,在下面生成Pannel面板的,可在PanelManager.cs中更换标签)

2.新建一个自己的Panel叫ImagePanel,只有按钮,icon和显示数字的文本.拖成Prefab,如图在下面选择new,然后再输入框中输入image.assetbundle,单击回车(不回车不会生效,这一步之后,以后build AB资源的时候就会把这个prefab打包成AB资源,Unity4需要多写一些代码,Unity5一行代码就可以打包所有命名过的ab资源,打包这边框架里面已经写好了)
3.接下来开始写Lua脚本(可使用Sublime,LuaStudio,NotePad++等)
找到Lua文件夹
(1)在Logic文件夹下将它原来的GameManager名字改为GameManager_xx,新建我们自己的lua脚本命名为GameManager.lua,代码如下.
require "Common/define"
require "Controller/ImageCtrl"
GameManager = {}
local this = GameManager
function GameManager.LuaScriptPanel()
return 'Image';
end
function GameManager.OnInitOK()
AppConst.SocketPort = 2012;
AppConst.SocketAddress = "127.0.0.1";
NetManager:SendConnect();
ImageCtrl.Awake()
end
(2)在View文件夹下新建ImagePanel.lua,代码如下
require "Common/define"
require "Controller/ImageCtrl"
GameManager = {}
local this = GameManager
function GameManager.LuaScriptPanel()
return 'Image';
end
function GameManager.OnInitOK()
AppConst.SocketPort = 2012;
AppConst.SocketAddress = "127.0.0.1";
NetManager:SendConnect();
ImageCtrl.Awake()
end
ImagePanel={}
local this = ImagePanel
local transform
local gameObject
function ImagePanel.Awake(obj)
gameObject = obj
transform = obj.transform
this.InitPanel()
end
function ImagePanel.InitPanel()
--获取ImagePanel上的按钮 lua里用: 和C#里的.一样
--在lua里变量名前没加local就是全局的
--所以add_btn可以直接在ImageCtrl中使用
this.add_btn = transform:FindChild("add_btn").gameObject
this.num_t = transform:FindChild("num_icon/num_t"):GetComponent("Text")
end
(3)在Controller文件夹下新建ImageCtrl.lua,代码如下
ImagePanel={}
local this = ImagePanel
local transform
local gameObject
function ImagePanel.Awake(obj)
gameObject = obj
transform = obj.transform
this.InitPanel()
end
function ImagePanel.InitPanel()
--获取ImagePanel上的按钮 lua里用: 和C#里的.一样
--在lua里变量名前没加local就是全局的
--所以add_btn可以直接在ImageCtrl中使用
this.add_btn = transform:FindChild("add_btn").gameObject
this.num_t = transform:FindChild("num_icon/num_t"):GetComponent("Text")
end
require "Common/define"
ImageCtrl = {}
local this = ImageCtrl
local transform
local gameObject
local lua
function ImageCtrl.New()
return this
end
function ImageCtrl.Awake()
PanelManager:CreatePanel("Image",this.OnCreate)
end
function ImageCtrl.OnCreate(obj)
gameObject = obj
transform = gameObject.transform
-- function.lua里面有可供调用的方法 可自己添加
rectTransform = gameObject:GetComponent("RectTransform")
rectTransform.localScale = Vector3(0.4,0.4,1)
message = gameObject:GetComponent('LuaBehaviour')
message:AddClick(ImagePanel.add_btn, this.OnAddBtnClick)
end
function ImageCtrl.OnAddBtnClick()
cnt = tonumber(ImagePanel.num_t.text)
ImagePanel.num_t.text = (cnt + 2)
end
4.打开AppConst.cs,进行一些设置.将DebugMode设置为true,将UpdateMode设置为false.然后选择菜单Game->build windows resources创建Windows下使用的ab资源. 此时运行程序,会解包ab资源,然后创建ImagePannel.(为了方便,运行程序之前可以把场景中的先隐藏,只留Lua代码中创建出来的)
require "Common/define"
ImageCtrl = {}
local this = ImageCtrl
local transform
local gameObject
local lua
function ImageCtrl.New()
return this
end
function ImageCtrl.Awake()
PanelManager:CreatePanel("Image",this.OnCreate)
end
function ImageCtrl.OnCreate(obj)
gameObject = obj
transform = gameObject.transform
-- function.lua里面有可供调用的方法 可自己添加
rectTransform = gameObject:GetComponent("RectTransform")
rectTransform.localScale = Vector3(0.4,0.4,1)
message = gameObject:GetComponent('LuaBehaviour')
message:AddClick(ImagePanel.add_btn, this.OnAddBtnClick)
end
function ImageCtrl.OnAddBtnClick()
cnt = tonumber(ImagePanel.num_t.text)
ImagePanel.num_t.text = (cnt + 2)
end

步骤三:更新
1. 创建1个文件夹模拟服务器, 将AppConst.cs下的 WebUrl改成文件夹的地址,如图所示.将StreamAssets下的所有东西拷到这个文件夹.

2. 对视图中的ImagePanel进行更改,比如将icon换成叶子,将按钮名称改成”点击+1”,apply到Prefab,将ImageCtrl.lua中的按钮点击事件逻辑改成点击+1.然后再Game->build windows 资源重新生成StreamAssets中的资源.运行程序,因为此时AppConst中的UpdateMode被我们关闭了,所以运行出来的ImagePanel是”叶子,点击+1”那个.

3. 将UpdateMode设置为true,DebugMode设置为false.此时运行会对比清单,从”服务器文件夹”下载更新,这时的ImagePanel已经变成了”金币,点击+2”那个了.(关于DebugMode,我们的Lua代码在Lua文件夹下有一份,在StreamAssets/Lua下有一份.我们写的是Lua下的那份,StreamAssets下的是build的时候生成的.更新的时候StreamAssets下的ab资源和lua脚本会被更新,如果开启DebugMode,直接用的是Lua文件夹下的那份而不是StreamAssets里面的,所以要把DebugMode关掉. )
4. 疑问:我在测试的过程中,发现DebugMode设置为false,打包资源的时候就会把C盘的simpleframework文件删掉,然后第一次运行需要解包的那次就报找不到文件,图片没加载出来.关掉再运行就可以.后来发现是C盘这个文件没有了,解包一次才会重新生成.所以我在build 资源的时候都会把DebugMode设置为true,测试更新的时候才把DebugMode设置为false,UpdateMode设置为true.