工具:VS、.2.3f、LuaStudio(方便编写Lua)、SimpleFramework_UGUI-0.3.7.2


Demo介绍如何使用uLua对UI进行热更新


【框架结构介绍】


unity使用 luban自定义末班 unity lua ui_Lua


Editor:一些编辑器扩展的脚本代码


Example:一个热更新例子介绍


Lua:实现热更新的核心lua代码


Source:实现热更新的核心C#代码


StreamingAssets:将生成的AssetBundles放入其中


uLua:luainterface代码lua与.net调用



【UI面板的创建】


我们要实现的功能是点击按钮A,弹出面板P,P中有个按钮B,点击按钮B,面板P隐藏


UI结构图如下图:


unity使用 luban自定义末班 unity lua ui_热更新_02


将SettingPanel、BackBoundPanel打包成一个预制体(预制体命名以'Panel'结尾)


并且将预制体分别设置为AssetBundle,分别命名为Setting.assetbundle、BackBound.assetbundle


可以参考AssetBundle的创建链接地址



【GameManager.lua代码的编写】


用LuaStudio打开Lua目录下的Lua.luapri,目录如下:


unity使用 luban自定义末班 unity lua ui_unity使用 luban自定义末班_03


由于本身的GameManager.lua是案例的,所以在这里我把它重新命名为GameManager.lua_pre


并且新建一个.lua脚本放在Logic文件夹下(不然C#无法读取到),命名为GameManager.lua


GameManager.lua文件代码如下:


纯文本查看  复制代码



?



 



01



02



03



04



05



06



07



08



09



10



11



12



13



14



15



16



17



18



19



20



21



22



23



24



25



26



27



28



29



30



31



32



require

"Common/define"


 



require

"Controller/BackGroundCtl"


require

"Controller/SettingCtl"


 


--管理器--


GameManager

={}

;



 


local

this

=

GameManager;



 



function GameManager.LuaScriptPanel

()



--C#执行该函数,获取以下两个字符串,自后会执行SettingPanel.lua、BackGroundPanel.lua



return

'Setting'

,

'BackGround';


end


 



function GameManager.Awake

()

end


 


--启动事件--


function GameManager.Start

()

end


 



 


--初始化完成,发送链接服务器信息--


function GameManager.OnInitOK

()



AppConst.SocketPort

= 2012

;




AppConst.SocketAddress

= "127.0.0.1"

;




NetManager

:

SendConnect

()

;



 




SettingCtl.Awake

()

;       




BackGroundCtl.Awake

()

;



 


end






【编写View层下的lua文件】



View下是编写显示层,一般获取其游戏对象上的组件或子对象


在View文件下添加SettingPanel.lua(注意新建文件时一定要将文件添加到View文件夹下,否则会报错滴)


SettingPanel.lua




在View文件下添加BackGroundPanel.lua(注意新建文件时一定要将文件添加到View文件夹下,否则会报错滴)


纯文本查看  复制代码



?



 



01



02



03



04



05



06



07



08



09



10



11



12



13



14



15



16



17



18



19



20



BackGroundPanel

={}

;



 


local

this

=

BackGroundPanel;



 


local

transform;


local

gameobject;



 



 



function BackGroundPanel.Awake

(

obj

)



gameobject

=

obj;




transform

=

obj.transform;



 




this.InitPanel

()

;


end


 



 



function BackGroundPanel.InitPanel

()



--获取其中Animator组件



this.anim

=

transform

:

GetComponent

("Animator")

;




this.ColseButton

=

transform

:

FindChild

("Button")

.gameObject;


end





【编写Controller文件下的lua文件】



Controller层一般处理动画、按钮点击事件等相关逻辑


在Controller文件下添加SettingCtl.lua(注意新建文件时一定要将文件添加到View文件夹下,否则会报错滴)


纯文本查看  复制代码



?



 



01



02



03



04



05



06



07



08



09



10



11



12



13



14



15



16



17



18



19



20



21



22



23



24



25



26



27



28



29



30



require

"Common/define"


 



SettingCtl

={}

;



 


local

this

=

SettingCtl;


local

gameobject;


local

setting;



 



function SettingCtl.New

()



return

this;


end


 



function SettingCtl.Awake

()



PanelManager

:

CreatePanel

("Setting",

this.OnCreate

)

;


end


 



 


--启动事件--


function SettingCtl.OnCreate

(

obj

)



gameobject

=

obj;



 




--添加事件响应--



setting

=

obj

:

GetComponent

(

'LuaBehaviour'

)

;




setting

:

AddClick

(

SettingPanel.buttonSetting

,

this.OnClick

)

;



 


end


 


--事件响应函数--


function SettingCtl.OnClick

()



BackGroundCtl.Show

()

;


end






在Controller文件下添加BackBoundCtl.lua(注意新建文件时一定要将文件添加到View文件夹下,否则会报错滴)


纯文本查看  复制代码



?



 



01



02



03



04



05



06



07



08



09



10



11



12



13



14



15



16



17



18



19



20



21



22



23



24



25



26



27



28



29



30



31



32



33



34



35



36



37



38



39



require

"Common/define"


 



BackGroundCtl

={}

;



 


local

this

=

BackGroundCtl;


local

gameobject;


local

backGround;



 



function BackGroundCtl.New

()



return

this;


end


 



function BackGroundCtl.Awake

()



PanelManager

:

CreatePanel

("BackGround",

this.OnCreate

)

;


end


 



 


--启动事件--


function BackGroundCtl.OnCreate

(

obj

)



gameobject

=

obj;



 




backGround

=

obj

:

GetComponent

("LuaBehaviour")

;




backGround

:

AddClick

(

BackGroundPanel.ColseButton

,

this.OnClick

)

;



 


end


 



 



function BackGroundCtl.OnClick

()



this.Hide

()

;


end


 



 



function BackGroundCtl.Show

()



BackGroundPanel.anim

:

SetBool

("IsShow",true)

;


end


 



 



function BackGroundCtl.Hide

()



BackGroundPanel.anim

:

SetBool

("IsShow",false)

;


end





这样Lua下代码逻辑编写完成



【修改C#代码】


接下来需要C#有些代码细节需要改改


一.按如下图找到打开PanelManager.cs文件


unity使用 luban自定义末班 unity lua ui_Lua_04


按如下图修改


unity使用 luban自定义末班 unity lua ui_unity使用 luban自定义末班_05


GameObject go = GameObject.FindWithTag("Canvas");

将Tag修改为Canvas,意思是AssetBundle将加载到Tag为Canvas对象上(可以自行选择把实例化对象加载到自定义的对象上)



所以将画布的Tag修改为Canvas


unity使用 luban自定义末班 unity lua ui_lua_06


二.按如下图目录找到打开Util.cs文件


unity使用 luban自定义末班 unity lua ui_Lua_07


在最后几行按如下图修改:


这个修改可以说是框架的一个小Bug,以后版本可能会完善


unity使用 luban自定义末班 unity lua ui_Lua_08


三.按如下图找到AppConst.cs文件


unity使用 luban自定义末班 unity lua ui_unity_09


修改后的AppConst.cs文件代码:


纯文本查看  复制代码



?



 



01



02



03



04



05



06



07



08



09



10



11



12



13



14



15



16



17



18



19



20



21



22



23



24



25



26



27



28



29



30



31



32



33



34



35



36



37



38



39



40



41


using UnityEngine;



using System;



using System.Collections;



using System.Collections.Generic;



 



namespace SimpleFramework {



public class AppConst {



public const bool DebugMode = false ;                       //调试模式-用于内部测试



/// <summary>



/// 如果想删掉框架自带的例子,那这个例子模式必须要



/// 关闭,否则会出现一些错误。



/// </summary>



public const bool ExampleMode = true ;                       //例子模式



 



/// <summary>



/// 如果开启更新模式,前提必须启动框架自带服务器端。



/// 否则就需要自己将StreamingAssets里面的所有内容



/// 复制到自己的Webserver上面,并修改下面的WebUrl。



/// </summary>



public const bool UpdateMode = true ;                       //更新模式-默认关闭



 



public const int TimerInterval = 1;



public const int GameFrameRate = 30;                       //游戏帧频



 



public const bool UsePbc = true ;                           //PBC



public const bool UseLpeg = true ;                          //LPEG



public const bool UsePbLua = true ;                         //Protobuff-lua-gen



public const bool UseCJson = true ;                         //CJson



public const bool UseSproto = true ;                        //Sproto



public const bool LuaEncode = false ;                        //使用LUA编码



 



public const string AppName = "SimpleFramework" ;           //应用程序名称



public const string AppPrefix = AppName + "_" ;             //应用程序前缀



public const string ExtName = ".assetbundle" ;              //素材扩展名



public const string AssetDirname = "StreamingAssets" ;      //素材目录



public const string WebUrl = "http://192.168.1.102:6688/" ;      //测试更新地址



 



public static string UserId = string .Empty;                 //用户ID



public static int SocketPort = 0;                           //Socket服务器端口



public static string SocketAddress = string .Empty;          //Socket服务器地址



}



}






更新模式:为false时,不连接服务器;为true时,连接服务器更新(接下来会介绍怎么开启服务器)



【连接服务器更新模式】


按如上图方式将WebUrl改为


纯文本查看  复制代码



?



 



public const

string

WebUrl

= "http://192.168.1.102:6688/"

;     

//

测试更新地址







Url地址为局域网下的IP地址(获取IP地址方式在这里就不介绍了)



接下来是用VS开启..\SimpleFramework_UGUI-0.3.7.2\Server目录下的server.sln文件


按如下图在文件下的host地址更改下


unity使用 luban自定义末班 unity lua ui_unity_10


接下来重新生成下


之后在..\SimpleFramework_UGUI-0.3.7.2\Server\Server\bin\Debug目录下找到SuperSocket.SocketService.exe文件


右键按管理员身份运行


输入r开始运行服务器


unity使用 luban自定义末班 unity lua ui_unity使用 luban自定义末班_11


最后按如下图步骤执行并将更新模式改为true


unity使用 luban自定义末班 unity lua ui_热更新_12

unity使用 luban自定义末班 unity lua ui_unity使用 luban自定义末班_13


最后开始运行游戏,客户端也接收到了数据


unity使用 luban自定义末班 unity lua ui_Lua_14