实现:使用SimpleFramework实现热更新方式创建UI面板
注:文章使用的是UGUI的框架
1.下载框架
ulua官方地址:http://www.ulua.org/
SimpleFramework UGUI Github地址:https://github.com/jarjin/SimpleFramework_UGUI/
下载完成后为项目文件,可直接使用unity打开,目录结构如下图:
Examples/Scenes文件下放的为热更新示例项目,ulua/Examples文件夹下放的为ulua语法教程示例
2.新建场景
- 新建一个自己要测试的场景
- 创建需要热更新的面板Prefab
- 新建一个GameObject添加Global Generator脚本组件
层次面板目录结构:
注意:需要热更新的UI面板要以“Panel”名字结尾
3.打包文件
-
将TextFramePanel预制体打包进 textframe.assetbundle
-
单击菜单栏中 Lua/Gen Lua Wrap Files ,如果生成成功在ulua/Source/LuaWrap文件夹下看到许多包裹文件,这些文件原来是没有的。
-
如果修改了注册到Lua中的C#类,需要清除文件缓存,重新生成。单击Lua/Clear LuaBinder File + Wrap Files再接第二步
-
单击菜单栏中Game/Build XXX Resources 打包资源文件
-
打包成功会在项目文件夹中生成StreamingAssets文件夹,目录结构如下:
注:
- 红框中为我的打包文件,其他为示例项目打包的资源文件
- 如果目标平台时Android,需要现在Build Settings中切换平台为安卓,然后再重新生成打包
如果在生成包裹文件后出现以下类似错误:
Assets/Source/LuaWrap/xxxWrap.cs(218,21): error CS1061: Type UnityEngine.xxx' does not contain a definition for
xxx' and no extension method xxx' of type
UnityEngine.xxx' could be found (are you missing a using directive or an assembly reference?)
官方给出的解决方案:因为unity不同平台版本api各不相同,因此不是特别统一,遇到此问题直接删除错误代码即可.
4.修改C#脚本
1.PanelManager.cs
Transform Parent {
get {
if (parent == null) {
GameObject go = GameObject.FindWithTag("Canvas");//原标签为"GuiCamera"
if (go != null) parent = go.transform;
}
return parent;
}
}
因为我的TextFramePanel是直接放在Canvas下的,而原框架中是放在GuiCamera下的,所以我将Canvas添加了一个“Canvas”的标签来作为面板的父物体。
2.AppView.cs
void OnGUI() {
GUI.Label(new Rect(10, 120, 960, 50), message);
GUI.Label(new Rect(10, 0, 500, 50), "(1) 单击 \"Lua/Gen Lua Wrap Files\"。");
GUI.Label(new Rect(10, 20, 500, 50), "(2) 运行Unity游戏");
GUI.Label(new Rect(10, 40, 500, 50), "PS: 清除缓存,单击\"Lua/Clear LuaBinder File + Wrap Files\"。");
GUI.Label(new Rect(10, 60, 900, 50), "PS: 若运行到真机,请设置Const.DebugMode=false,本地调试请设置Const.DebugMode=true");
GUI.Label(new Rect(10, 80, 500, 50), "PS: 加Unity+ulua技术讨论群:>>341746602");
}
这些是框架的提示信息,可自行修改或删除
3.AppConst.cs
public const bool DebugMode = false; //调试模式-用于内部测试,默认为true
public const bool UpdateMode = true; //更新模式-默认为false
public const string WebUrl = "http://192.168.3.9:6688/"; //测试更新地址,默认为localhost
192.168.3.9位本机IP地址
4.HttpServer.cs
修改框架自带的服务器端host地址,即Server/Server.sln中的HttpServer.cs
public HttpServer(int port) {
host = "http://192.168.3.9:6688/";
}
5.修改Lua脚本
1.打开项目文件夹
这里可以使用Sublime Text 的 File/Open Folder打开框架中的Lua文件夹,能够清楚的看到文件夹结构。
不过第一次打开也会将所有.meta文件显示出来,显得比较乱,可以参考这里来屏蔽特定文件类型
##2.函数调用顺序
GameManager.cs
/// <summary>
/// 资源初始化结束
/// </summary>
public void OnResourceInited() {
LuaManager.Start();
LuaManager.DoFile("Logic/Network"); //加载游戏
LuaManager.DoFile("Logic/GameManager"); //加载网络
initialize = true;
NetManager.OnInit(); //初始化网络
object[] panels = CallMethod("LuaScriptPanel");
//---------------------Lua面板---------------------------
foreach (object o in panels) {
string name = o.ToString().Trim();
if (string.IsNullOrEmpty(name)) continue;
name += "Panel"; //添加
LuaManager.DoFile("View/" + name);
Debug.LogWarning("LoadLua---->>>>" + name + ".lua");
}
//------------------------------------------------------------
CallMethod("OnInitOK"); //初始化完成
}
从以上可以看出Lua函数的调用顺序为
GameManager.LuaScriptPanel()-->View/TextFramePanel.lua-->GameManager.OnInitOK()
这里即将控制权交给了Lua文件
3.Logic/GameManger.lua
require "Common/define"
require "Controller/TextFrameCtrl"
GameManager={}
local this = GameManager
function GameManager.LuaScriptPanel()
return 'TextFrame'
end
function GameManager.OnInitOK()
AppConst.SocketPort = 2012
AppConst.SocketAddress = "127.0.0.1"
NetManager:SendConnect()
TextFrameCtrl.Awake()
warn("SimpleFramework start!");
end
4.View/TextFramePanel.lua
local transform
local gameObject
TextFramePanel = {};
local this = TextFramePanel;
function TextFramePanel.Awake(obj)
-- body
gameObject = obj
transform = obj.transform
this.InitPanel()
end
function TextFramePanel.InitPanel()
--测试热更新文本
this.textshow = transform:FindChild("BG/Text").gameObject;
end
5.Controller/TextFrameCtrl.lua
require "Common/define"
local label
local textframe
local transform
local gameObject
TextFrameCtrl = {}
local this = TextFrameCtrl
function TextFrameCtrl.New()
-- body
return this
end
function TextFrameCtrl.Awake()
-- body
PanelManager:CreatePanel("TextFrame", this.OnCreate);--创建面板,调用回调函数
end
--启动事件--
function TextFrameCtrl.OnCreate(obj)
-- body
gameObject = obj
transform = obj.transform
label = TextFramePanel.textshow:GetComponent("Text")
label.text = "oh, come on man!"
end
6.启动服务器测试
1.Build安卓apk
当服务器没有打开时,打开APK如下图:
2.启动服务器
以管理员方式启动Server\Server\bin\Debug下的SuperSocket.SocketService.exe
启动后显示图:
此时再重启APK:
ok!
如果更新失败可以测试一下手机是否能连接电脑主机端口,即在浏览器中输入 本机IP:端口号
例如:192.168.3.9:6688 输入后能显示下图即连接成功
如果连接不上可以试试如下方法:
http://jingyan.baidu.com/article/67508eb4dc85e79cca1ce48f.html
7.热更新测试
更新内容:修改文本框中的文字为“更新完成”,并且删除面板中间的那张图片
1.修改Controller/TextFrameCtrl.lua
--启动事件--
function TextFrameCtrl.OnCreate(obj)
-- body
gameObject = obj
transform = obj.transform
label = TextFramePanel.textshow:GetComponent("Text")
label.text = "更新完成"
end
2.修改TextFramePanel预制体
将预制体中的图片删除,结构如下:
然后重新Build Android Resource,重新启动安卓客户端:
完!