[Unity热更新]tolua# & LuaFramework(十五):更新下载(下)

继续承接上一篇:http://blog.csdn.net/lyh916/article/details/52201952

上一篇是使用OnGUI展示的,这次用lua改写一下。


效果图:

[Unity热更新]tolua# & LuaFramework(十五):更新下载(下)_第1张图片


一.创建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(修改的地方很小,直接截图):

[Unity热更新]tolua# & LuaFramework(十五):更新下载(下)_第2张图片

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

LuaHelper.cs(添加方法,方便调用GameManager.cs中的SecondExtractAndUpdate方法):

        public static GameManager GetGameManager()
        {
            return AppFacade.Instance.GetManager(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 list = new List();

    ///
    /// 监听的消息
    ///
    List MessageList {
        get {
            return new List()
            { 
                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);
    }

    /// 
    /// 处理View消息
    /// 
    /// 
    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地址。

你可能感兴趣的:(Unity热更新)