LuaFramework 第三章 热更新

本片将代码的热更新和资源的热更新,首先先讲本地的热更新,之后讲网络的热更新

首先是本地的

这里先从网上随便找的资源,找了一个性感的女战士模型,和随意组成的一个UI界面
制作完成后,将物体拖到project视图里面做成预制体(这里要选好地址放这些预制体,因为预制体是要打成assetBundle包,然后再去加载的,而这些路径后面是要用到的

然后讲预制体的贴图之类的也放到专门的目录里面
这里是专门当反面教材用的,所以没有具体的放到专门的地方,请勿学习
这里写图片描述

放好之后就要开始改动脚本了,首先是Packager.cs

/// <summary>
/// 处理框架实例包
/// </summary>
static void HandleExampleBundle() {
    string resPath = AppDataPath + "/" + AppConst.AssetDir + "/";
    if (!Directory.Exists(resPath)) Directory.CreateDirectory(resPath);

    AddBuildMap("prompt" + AppConst.ExtName, "*.prefab", "Assets/LuaFramework/Examples/Builds/Prompt");
    AddBuildMap("message" + AppConst.ExtName, "*.prefab", "Assets/LuaFramework/Examples/Builds/Message");

    AddBuildMap("prompt_asset" + AppConst.ExtName, "*.png", "Assets/LuaFramework/Examples/Textures/Prompt");
    AddBuildMap("shared_asset" + AppConst.ExtName, "*.png", "Assets/LuaFramework/Examples/Textures/Shared");

   AddBuildMap("ui" + AppConst.ExtName, "*.prefab", "Assets/UI/Prefabs");
   AddBuildMap("ui_asset" + AppConst.ExtName, "*.jpg", "Assets/UI/Altas");
}

</php>

这里要添加自己自己的资源的路径,并设置名称等;我这里添加了 这两行,这些可以自行命名;
AddBuildMap(“ui” + AppConst.ExtName, “*.prefab”, “Assets/UI/Prefabs”);
AddBuildMap(“ui_asset” + AppConst.ExtName, “*.jpg”, “Assets/UI/Altas”);

然后,因为要创建物体,我改动了一下ResourceManager.cs(LuaFramework/Scripts/Manager),其实不用改动的,不过我方法既然已经添加了,也懒得删了所以就直接也给大家看看了, 这个地方后期根据自己的理解可以 删了的,当时第一眼没看见里面已经有一个加载方法了

在里面添加了一个方法


/// 新添加从bundle中 读取prefab的函数

    public GameObject LoadPrefab(string bundleName, string prefabName, LuaFunction func)
    {
        GameObject newPrefab = null;
        string uri =bundleName + AppConst.ExtName;
        Debug.LogWarning("@LoadPrefab:LoadFile::>> " + uri);
        AssetBundle ab = LoadAssetBundle(uri);
#if UNITY_5
        newPrefab = ab.LoadAsset(prefabName, typeof(GameObject)) as GameObject;
#else
        newPrefab = ab.Load("prefabName", typeof(GameObject)) as GameObject;
#endif
        if (func != null)
        {
            func.Call();    //资源获取成功,回调func,执行后续操作 
        }
        return newPrefab;
    }

然后就需要改动lua的方法了,
首先,既然使用了puremvc的方法,就肯定要创建Cotrller和view层,并且由于创建的命令这些和之前的一样所以命令没有改动

然后需要创建Ctrl和View脚本 我是在LuaFramework/Lua/View 下创建了一个uiPanel.lua的lua脚本,然后再在LuaFramework/Lua/Controller下创建了一个uiCtrl.lua的lua脚本

这是uiPanel的内容

<lua>
local transform;
local gameObject;
uiPanel = {};
local this = uiPanel;
--启动事件--
function uiPanel.Awake(obj)
gameObject = obj;
transform = obj.transform;

this.InitPanel();
logWarn("Awake lua--->>"..gameObject.name);
end
--初始化面板--
function uiPanel.InitPanel()
this.btnOpen = transform:Find("Image").gameObject;
this.btnOpen .name="test"
end

--单击事件--
function uiPanel.OnDestroy()
logWarn("OnDestroy---->>>");
end

看着是不是和C#一毛一样?其实差不多
然后是uiCtrl

    require "Common/define"
    require "3rd/pblua/login_pb"
    require "3rd/pbc/protobuf"
    local sproto = require "3rd/sproto/sproto"
    local core = require "sproto.core"
    local print_r = require "3rd/sproto/print_r"




    uiCtrl = {};
    local this = uiCtrl;

    local panel;
    local prompt;
    local transform;
    local gameObject;

    --构建函数--
    function uiCtrl.New()
        logWarn("uiCtrl.New--->>");
        return this;
    end

    function uiCtrl.Awake()
        logWarn("uiCtrl.Awake--->>");
        panelMgr:CreatePanel('ui', this.OnCreate);
    end

    --启动事件--
    function uiCtrl.OnCreate(obj)
        gameObject = obj;
        transform = obj.transform;

panel = transform:GetComponent('uiPanel');
prompt = transform:GetComponent('LuaBehaviour');
logWarn("Start lua--->>"..gameObject.name);
local btn=transform:Find('btn').gameObject;
btn.name="btnsss"
prompt:AddClick(btn, this.OnItemClick);
end
 isLoad=0
--滚动项单击--
function uiCtrl.OnItemClick(go)
    log(go.name);


if  isLoad then
LuaFramework.Util.Log("*******lua脚本新建--一个人物--开始*******");
local   LuaHelper = LuaFramework.LuaHelper;
local  resMgr = LuaHelper.GetResManager();
local cube =  resMgr:LoadPrefab('ui', 'character', OnLoadPrefabFinish);
local go = UnityEngine.GameObject.Instantiate(cube);
--go.transform.position = Vector3(0,0,0);
LuaFramework.Util.Log("*******lua脚本新建--一个人物--完成*******");
isLoad=nil
end
end

--关闭事件--
function uiCtrl.Close()
    panelMgr:ClosePanel(CtrlNames.Prompt);
end

这是控制界面所需要的两个脚本,然后有了脚本之后就要开始改动原来的脚本了首先根据脚本的调用流程,先改动Game.lua(LuaFramework/Lua/Logic)里面的内容,首先根据调用的方法,

CtrlManager.Init();
local ctrl = CtrlManager.GetCtrl(CtrlNames.UI);
if ctrl ~= nil and AppConst.ExampleMode == 1 then
    ctrl:Awake();
end

这里是调用要显示哪个UI的地方,通过CtrlManager找到对应的Ctrl,并调用其中的Awake方法来实例化物体,这里是通过string 获取的,,你可以在GetCtrl();中直接写入名称,也可以在其他地方先声明好名称。这里是在define.lua(LuaFramework/Lua/Common)里面添加了一些名称,(这个类是框架中存放一些协议和指定的string的)

   CtrlNames = {
Prompt = "PromptCtrl",
Message = "MessageCtrl",
    UI = "uiCtrl"
}

PanelNames = {
    "PromptPanel",  
    "MessagePanel",
        "uiPanel",
}

在CtrlNames和PanelNames中都添加了一些名字, 然后改动了Game.lua(LuaFramework/Lua/Logic)里面的 local ctrl = CtrlManager.GetCtrl(CtrlNames.UI); GetCtrl中的名称,让他去创建我自己的物体

然后要在控制器中添加并注册我们写的uiCtrl和uiPanel这两个脚本 ,,找到CtrlManager.lua(LuaFramework/Lua/Logic)注册脚本,这是我改动之后的CtrlManager

require "Common/define"
require "Controller/PromptCtrl"
require "Controller/MessageCtrl"
require "Controller/uiCtrl"
CtrlManager = {};
local this = CtrlManager;
local ctrlList = {};    --控制器列表--

function CtrlManager.Init()
    logWarn("CtrlManager.Init----->>>");
    ctrlList[CtrlNames.Prompt] = PromptCtrl.New();
    ctrlList[CtrlNames.Message] = MessageCtrl.New();
        ctrlList[CtrlNames.UI] = uiCtrl.New();
    return this;
end

--添加控制器--
function CtrlManager.AddCtrl(ctrlName, ctrlObj)
    ctrlList[ctrlName] = ctrlObj;
end

--获取控制器--
function CtrlManager.GetCtrl(ctrlName)
    return ctrlList[ctrlName];
end

--移除控制器--
function CtrlManager.RemoveCtrl(ctrlName)
    ctrlList[ctrlName] = nil;
end

--关闭控制器--
function CtrlManager.Close()
    logWarn('CtrlManager.Close---->>>');
end

需要添加require引用对应的Ctrl模块,并在Init中将自己的Ctrl模块new出来

之后就是重新生成warp文件和打包,重新生成的话,需要先将原来的清除掉,所以要用编辑器里的lua/Clear warp files 然后会提示你重新生成,生成

打包的话打成你所在平台的包,这里使用的直接是window平台,就直接用Bulid Windows Resource 了

,之后就直接点击运行,第一次运行会经过解压步骤,时间会长一点,可以在log日志里面看到解压的信息等一下就加载出来了,显示出来

这里是点击一下按钮,创建人物的可以在hierarchy里面看到人物的名称后面是由(Clone)的
这里写图片描述

至此,本地的打包更新就完成了。

下面是网络的更新,,

首先,你需要一个组件内网的工具,我这里使用了 Everything的,,安装之后直接, 工具/选项/HTTP 服务器。。然后勾选启用HTTP服务器,就把自己的电脑转成了可用内网访问的了,之后就是就需要改动c#脚本了

其实也就只需要改动一个脚本就是AppConst.cs ((LuaFramework/Scripts/ConstDefine)) 首先将脚本里面的UpdateMode,改为true,然后将WebUrl改成你要更新到的目录(这个目录下面会说)

<php> 
            /// <summary>
    /// 如果开启更新模式,前提必须启动框架自带服务器端。
    /// 否则就需要自己将StreamingAssets里面的所有内容
    /// 复制到自己的Webserver上面,并修改下面的WebUrl。
    /// </summary>
    public const bool UpdateMode = true  ;                       //更新模式-默认关闭 
    public const bool LuaByteMode = false;                       //Lua字节码模式-默认关闭 
    public const bool LuaBundleMode = true;                    //Lua代码AssetBundle模式

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

    public const string AppName = "LuaFramework";               //应用程序名称
    public const string LuaTempDir = "Lua/";                    //临时目录
    public const string AppPrefix = AppName + "_";              //应用程序前缀
    public const string ExtName = ".unity3d";                   //素材扩展名
    public const string AssetDir = "StreamingAssets";           //素材目录 
    public const string WebUrl = "http://192.168.1.105/F%3A/%E7%AD%89%E4%BC%9A%E5%88%A0%E4%BA%86/StreamingAssets/";      //测试更新地址
</php>

这实我改之后的样子,WebUrl要根据你自身的ip来确定

然后就需要你将StreamingAssets里面的所有内容,都复制到自己的Webserver上面,并修改的WebUrl。所以,我把工程里面的StreamingAssets文件随便拷贝到了一个地方然后设置一下WebUrl 就可以了,这不!这里写图片描述

这里这文件的位置等会要设置成你WebUrl的路径

其实至此 更新已经完成了。。

接下来就是测试的了,因为我是直接在编辑器里面试的,这就有点绕了,
我先把原来的那份拷贝到了那个位置,所以在等会删了 问价夹下的,是我的老的StreamingAssets,点击人物的时候log显示的是

lua脚本新建–一个人物–开始
lua脚本新建–一个人物–完成

这两个提示,,我先把AppConst.cs里的 public const bool UpdateMode = false ; //更新模式-默认关闭 设成了false,以便我改动的时候在本地测试一下

然后我把uiCtrl.lua 中的这两个 log的输入改了一下

LuaFramework.Util.Log("*******lua脚本新建--性感的小姐姐--开始*******");
    LuaFramework.Util.Log("*******lua脚本新建--性感的小姐姐--完成*******");

改成了这样

然后再打包一下,由于UpdateMode 设成了false,此时更新模式是关闭的,所以,会加载本地的StreamingAssets,测试lua脚本改动是否成功,这里显示是成功了的这里写图片描述

然后我再把AppConst.cs里的 public const bool UpdateMode = false ; //更新模式-默认关闭 设成了true, 此时是出于更新模式的,
然后经过一系列的请求之后再次点击显示的log为这样的这里写图片描述

说明我们新改动之后的lua脚本没有运行,而是运行的从web服务器上加载的原先的lua脚本,,说明现在的项目是以服务器上的为准的,

热更实现成功!!

新手小白出品,如有写的有问题,请及时告知!谢谢

猜你喜欢

转载自blog.csdn.net/qq_37574876/article/details/80708895
今日推荐