继续承接上一篇:http://blog.csdn.net/lyh916/article/details/52201952
上一篇是使用OnGUI展示的,这次用lua改写一下。
效果图:
一.创建lua模板
找到unity安装目录\Editor\Data\Resources\ScriptTemplates,把下面两个模板文件放进去,重启unity,即可方便地创建lua文件
88-ToLua# Panel Script-Panel.lua.txt
#SCRIPTNAME# = {}; local this = #SCRIPTNAME#; local gameObject; local transform; --由LuaBehaviour自动调用 function #SCRIPTNAME#.Awake(obj) gameObject = obj; transform = obj.transform; --this.gridText = transform:FindChild('ScrollView/Grid'):GetComponent('Text'); end --由LuaBehaviour自动调用 function #SCRIPTNAME#.Start() end 89-ToLua# Ctrl Script-Ctrl.lua.txt require "Common/define" #SCRIPTNAME# = {}; local this = #SCRIPTNAME#; local gameObject; local transform; function #SCRIPTNAME#.New() return this; end function #SCRIPTNAME#.Awake() panelMgr:CreatePanel('Prompt', this.OnCreate);--需修改处 end function #SCRIPTNAME#.OnCreate(obj) gameObject = obj; transform = obj.transform; --go.transform.localPosition = Vector3.zero; end
二.上一篇是一次解包后自动进行二次解包并更新,为了增强灵活性,改为手动调用方式
修改下面两个文件并重新生成wrap:
GameManager.cs(修改的地方很小,直接截图):
LuaHelper.cs(添加方法,方便调用GameManager.cs中的SecondExtractAndUpdate方法):
public static GameManager GetGameManager() { return AppFacade.Instance.GetManager<GameManager>(ManagerName.Game); }
好了,如无意外就能手动地进行二次解包和更新了。
三.使用框架自带的事件中心
回顾一下框架的网络模块,它使用了框架自带的事件中心:
a.在Network.lua中,进行了事件的注册
b.在SocketCommand.cs中,通过c#调用lua,将事件传递到lua中
c.再次回到Network.lua中,通过OnSocket方法进行了事件的分发
上一篇是通过AppView.cs来展示信息的,那么现在就把这些信息传递到lua中进行展示(即c#调用lua),通过上面的b步骤得知c#调用lua的方式为Util.CallMethod("Network", "OnSocket", name, body);。并且,还要在lua中定义事件类型。
添加EventType.lua(仿照NotiConst.cs):
EventType = { --这几个是和NotiConst.cs对应的 --解包要展示的相关参数 EXTRACT_FILE_NAME = "EXTRACT_FILE_NAME", --解包文件名 EXTRACT_FINISH_ONE = "EXTRACT_FINISH_ONE", --解包完一个文件 EXTRACT_ALL_COUNT = "EXTRACT_ALL_COUNT", --解包总文件数 --更新要展示的相关参数 UPDATE_SPEED = "UPDATE_SPEED", --下载速度 UPDATE_FILE_NAME = "UPDATE_FILE_NAME", --下载文件名 UPDATE_FINISH_ONE = "UPDATE_FINISH_ONE", --下载完一个文件 UPDATE_ALL_COUNT = "UPDATE_ALL_COUNT", --下载总文件数 } 修改AppView.cs:这里要注意,Util.CallMethod("Network", "OnSocket", name, body);这句代码不能放在OnMessage方法中,否则会报get_gameObject can only be called from the main thread.的错误并直接卡死,具体原因不明,但SocketCommand.cs安全地调用lua。能解决方法就是放在MonoBehaviour的方法里面吧。
using UnityEngine; using LuaFramework; using System.Collections.Generic; public class AppView : View { private string message; private List<IMessage> list = new List<IMessage>(); ///<summary> /// 监听的消息 ///</summary> List<string> MessageList { get { return new List<string>() { NotiConst.EXTRACT_FILE_NAME, NotiConst.EXTRACT_FINISH_ONE, NotiConst.EXTRACT_ALL_COUNT, NotiConst.UPDATE_SPEED, NotiConst.UPDATE_FILE_NAME, NotiConst.UPDATE_FINISH_ONE, NotiConst.UPDATE_ALL_COUNT, }; } } void Awake() { RemoveMessage(this, MessageList); RegisterMessage(this, MessageList); } /// <summary> /// 处理View消息 /// </summary> /// <param name="message"></param> public override void OnMessage(IMessage message) { list.Add(message); } string extractFileName; int extractNowCount = 0; int extractAllCount = 0; string updateFileName; int updateNowCount = 0; int updateAllCount = 0; string updateSpeed; void Update() { if (list.Count > 0) { IMessage message = list[0]; string name = message.Name; object body = message.Body; if (AppConst.UpdateMode) { Util.CallMethod("Network", "OnSocket", name, body); list.RemoveAt(0); return; } this.message = message.Name; switch (name) { case NotiConst.EXTRACT_FILE_NAME: extractFileName = body.ToString(); break; case NotiConst.EXTRACT_FINISH_ONE: extractNowCount++; break; case NotiConst.EXTRACT_ALL_COUNT: extractAllCount = (int)body; break; case NotiConst.UPDATE_SPEED: updateSpeed = body.ToString(); break; case NotiConst.UPDATE_FILE_NAME: updateFileName = body.ToString(); break; case NotiConst.UPDATE_FINISH_ONE: updateNowCount++; break; case NotiConst.UPDATE_ALL_COUNT: updateAllCount = (int)body; break; } list.RemoveAt(0); } } //void OnGUI() //{ // if (string.IsNullOrEmpty(message)) return; // if (message.StartsWith("EXTRACT_")) // { // GUILayout.Label("正在解包的文件:" + extractFileName); // GUILayout.Label("当前解包数:" + extractNowCount); // GUILayout.Label("总的解包数:" + extractAllCount); // } // else if (message.StartsWith("UPDATE_")) // { // GUILayout.Label("正在下载的文件:" + updateFileName); // GUILayout.Label("当前下载数:" + updateNowCount); // GUILayout.Label("总的下载数:" + updateAllCount); // GUILayout.Label("下载速度:" + updateSpeed); // } //} }四.最后,就是在lua中展示信息了。
关于如何快速调试:在编写lua文件时不免会出错,为了加快效率,建议将AppConst.cs中的UpdateMode和LuaBundleMode改为false,这样就无需连接本地服务器,并且直接读取本地的lua文件了。
require "Common/define" require "Logic/UIPanelBase" require "Common/EventType" Event = require 'events' StartCtrl = UIPanelBase:New(); local this = StartCtrl; local gameObject; local transform; local tweener; local extractFileName; local extractNowCount = 0; local extractAllCount = 0; local updateFileName; local updateNowCount = 0; local updateAllCount = 0; local updateSpeed; local progressBar; local countLabel; local speedLabel; local fileNameLabel; function StartCtrl.New() return StartCtrl; end function StartCtrl.Awake() panelMgr:CreatePanel('Start', StartCtrl.OnCreate); end function StartCtrl.OnCreate(obj) gameObject = obj; transform = obj.transform; StartCtrl.gameObject = obj; StartCtrl.transform = obj.transform; progressBar = transform:FindChild("ProgressBar"):GetComponent('UISlider'); countLabel = transform:FindChild("CountLabel"):GetComponent('UILabel'); speedLabel = transform:FindChild("SpeedLabel"):GetComponent('UILabel'); fileNameLabel = transform:FindChild("FileNameLabel"):GetComponent('UILabel'); Event.AddListener(EventType.EXTRACT_FILE_NAME, this.EXTRACT_FILE_NAME); Event.AddListener(EventType.EXTRACT_FINISH_ONE, this.EXTRACT_FINISH_ONE); Event.AddListener(EventType.EXTRACT_ALL_COUNT, this.EXTRACT_ALL_COUNT); Event.AddListener(EventType.UPDATE_SPEED, this.UPDATE_SPEED); Event.AddListener(EventType.UPDATE_FILE_NAME, this.UPDATE_FILE_NAME); Event.AddListener(EventType.UPDATE_FINISH_ONE, this.UPDATE_FINISH_ONE); Event.AddListener(EventType.UPDATE_ALL_COUNT, this.UPDATE_ALL_COUNT); --如果Panel以动画形式出现,那么确保设置PanelManager.cs实例化出来的Panel为隐藏状态 StartCtrl:Open(); --用于本地测试 --[[ Event.Brocast(EventType.EXTRACT_FILE_NAME, "wakaka"); Event.Brocast(EventType.EXTRACT_FINISH_ONE, 0); Event.Brocast(EventType.EXTRACT_ALL_COUNT, 6);--]] --[[ Event.Brocast(EventType.UPDATE_SPEED, "123kb/s"); Event.Brocast(EventType.UPDATE_FILE_NAME, "wakaka2"); Event.Brocast(EventType.UPDATE_FINISH_ONE, 0); Event.Brocast(EventType.UPDATE_ALL_COUNT, 66);--]] end function StartCtrl.EXTRACT_FILE_NAME(data) StartCtrl.EXTRACT(); extractFileName = tostring(data); fileNameLabel.text = "正在解包:" .. extractFileName; end function StartCtrl.EXTRACT_FINISH_ONE(data) StartCtrl.EXTRACT(); extractNowCount = extractNowCount + 1; countLabel.text = extractNowCount .. " / " .. extractAllCount; progressBar.value = extractNowCount / extractAllCount; end function StartCtrl.EXTRACT_ALL_COUNT(data) StartCtrl.EXTRACT(); extractAllCount = Util.Float(data); countLabel.text = extractNowCount .. " / " .. extractAllCount; progressBar.value = extractNowCount / extractAllCount; end function StartCtrl.UPDATE_SPEED(data) StartCtrl.UPDATE(); updateSpeed = tostring(data); speedLabel.text = "速度:" .. updateSpeed; end function StartCtrl.UPDATE_FILE_NAME(data) StartCtrl.UPDATE(); updateFileName = tostring(data); fileNameLabel.text = "正在下载:" .. updateFileName; end function StartCtrl.UPDATE_FINISH_ONE(data) StartCtrl.UPDATE(); updateNowCount = updateNowCount + 1; countLabel.text = updateNowCount .. " / " .. updateAllCount; progressBar.value = updateNowCount / updateAllCount; end function StartCtrl.UPDATE_ALL_COUNT(data) StartCtrl.UPDATE(); updateAllCount = Util.Float(data); countLabel.text = updateNowCount .. " / " .. updateAllCount; progressBar.value = updateNowCount / updateAllCount; end function StartCtrl.EXTRACT() progressBar.gameObject:SetActive(true); countLabel.gameObject:SetActive(true); speedLabel.gameObject:SetActive(false); fileNameLabel.gameObject:SetActive(true); end function StartCtrl.UPDATE() progressBar.gameObject:SetActive(true); countLabel.gameObject:SetActive(true); speedLabel.gameObject:SetActive(true); fileNameLabel.gameObject:SetActive(true); end五.打包apk进行测试更新
在android中,localhost这个东西是用不了的,因此连接服务器需要具体的ip地址,要修改的地方如下:
1.服务端:HttpServer.cs中的构造函数
2.客户端:AppConst.cs中的WebUrl,以及Game.lua中的OnInitOK函数
在控制面板---网络和Internet---网络和共享中心,点击本地连接---详细信息,其中IPv4地址即为要填写的IP地址。