Unity3D熱更新之LuaFramework篇[09]--資源熱更新與代碼熱更新的具體實現


前言

在上一篇文章 Unity3D熱更新之LuaFramework篇[08]--熱更新原理及熱更服務器搭建 中,我介紹了熱更新的基本原理,並且着手搭建一台服務器。

本篇就做一個實戰練習,真正的來實現熱更新功能。

一、准備工作

1、制作一個用於熱更新的界面

此前我制作了一個大廳界面,並且放置了兩個按鈕:”排行榜“和”商城“,排行榜按鈕已經用於打開排行榜頁面。

所以,現在再制作一個商店頁面,當點擊商城按鈕的時候,打開商店頁面。

1)  制作ShopPanel界面。

a) 制作一個商店界面ShopPanel,界面上放一個標題和簡單的3個商品項。如下圖:

 

b)將ShopPanel做成預制體,放在Assets\LuaFramework\CustomPrj\Shop目錄下。

c)創建ShopPalel.lua和ShopCtrl.lua並做CtrlNames注冊和PanelNames注冊。ShopPanel.lua放在Assets\LuaFramework\Lua\View\Shop目錄下,ShopCtrl.lua放在Assets\LuaFramework\Lua\Controller\Shop目錄下。

d)在Packager.cs的HandleExampleBundle方法中添加打包ShopPanel的代碼;

        //打包准備測試用的ShopPanel預制體
        AddBuildMap("shop" + AppConst.ExtName, "*.prefab", "Assets/LuaFramework/CustomPrj/Shop");

 

2)  點擊商城按鈕顯示商店面板

a)  在HallPanel.lua中添加對商城按鈕的引用; 

local transform;
local gameObject;

HallPanel = {};
local this = HallPanel;

--啟動事件--
function HallPanel.Awake(obj)
    gameObject = obj;
    transform = obj.transform;

    this.InitPanel();
    logWarn("Awake lua--->>"..gameObject.name);
end

--初始化面板--
function HallPanel.InitPanel()
    logWarn("我是HallPanel,我被加載了.");

    --排行榜按鈕
    HallPanel.rankingBtn = transform:FindChild("BtnRanking").gameObject;

    --排行榜面板
    HallPanel.rankingPanel = transform.parent:Find("RankingPanel");

    --商店按鈕
    HallPanel.shopBtn = transform:FindChild("BtnShop").gameObject;

    --調用Ctrl中panel創建完成時的方法
    HallCtrl.OnCreate(gameObject);
end

function HallPanel.OnDestroy()
    logWarn("OnDestroy---->>>");
end
HallPanel.lua

b)  在HallCtrl.lua中添加商城按鈕的事件處理 

HallCtrl = {};
local this = HallCtrl;

local behaviour;
local transform;
local gameObject;

--構建函數--
function HallCtrl.New()
    logWarn("HallCtrl.New--->>");
    return this;
end

function HallCtrl.Awake()
    logWarn("HallCtrl.Awake--->>");

    logWarn("我是HallCtrl,我被加載了.");
end


--啟動事件--
function HallCtrl.OnCreate(obj)
    gameObject = obj;
    transform = obj.transform;

    UIEventEx.AddButtonClick(HallPanel.rankingBtn, function ()
        log("你點擊了排行榜按鈕");

        HallPanel.rankingPanel.gameObject:SetActive (true);
    end);

    UIEventEx.AddButtonClick(HallPanel.shopBtn, function ()
        log("你點擊了商店按鈕");

        --實例化商店面板
        local shopCtrl = CtrlManager.GetCtrl(CtrlNames.Shop);
        shopCtrl:Awake();
    end);
end

--單擊事件--
function HallCtrl.OnClick(go)
    destroy(gameObject);
end

--關閉事件--
function HallCtrl.Close()
    panelMgr:ClosePanel(CtrlNames.Hall);
end
HallCtrl.lua

3)  打包並運行

a)      執行Build Windows Resources操作,新添加的ShopPanel會被自動打進包里

b)      運行Unity,點擊“商城“按鈕,正確地打開了商店面板。

 

2、修改熱更配置

打開AppConst.cs腳本,

將UpdateMode設置為true;

將WebUrl的地址設置為http://192.168.0.110:8080/StreamingAssets/  

這個192.168.110是我本機的ip,8080是Tomcat的默認端口號,這里根據實際情況修改為自己的ip即可。

修改位置見下圖:

 

 

3、測試熱更服務器

1)將Assets下的StreamingAssets目錄整個復制到Tomcat下的webapps目錄,我這里是

I:\apache-tomcat-9.0.22\webapps。

2)在瀏覽器中輸入http://192.168.0.110:8080/StreamingAssets/files.txt 。

如果能獲取到files.txt的內容,則表明熱更服務器已經就緒。

 

二、資源熱更新

1、制作一個客戶端程序

熱更新涉及兩個操作方,一個是服務器,一個是客戶端。服務器已經就緒了,現在還缺少一個客戶端程序。

1)首先將unity工程轉換到Android平台,點擊Build Android Resource菜單重新生成打包資源。

2)待build完成后,將現在的項目打成一個apk包(注意將Hall場景放在0位置,以便首先加載這個場景)

 (打包的時候如果出現報錯說插件沖突和架構重復啥的,刪掉Plugins目錄下的x86目錄就好,保留x86_64目錄)

3)把StreamingAssets目錄復制到Tomcat的webapps目錄(之前的刪掉就行)。之前測試服務器的時候拷過去的是Windows版本資源,無法和安卓客戶端進行更新,所以這里需要重新拷貝。

4)安裝這個apk包到手機,手機應該和電腦位於同一局域網。我這里使用的是一個安裝在本機上的安卓模擬器。

5)運行剛安裝的程序。

能正常打開大廳場景,點擊商城按鈕,也能正常彈出商店界面。如下圖:

 

如果剛進游戲如果直接點擊不起作用,等一下再試(正在解壓資源)。

現在客戶端也已經就緒。

 

2、制作更新內容並上傳到熱更服務器;

       上一步的操作中,我們打了一個安卓包,並將此時的StreamingAssets目錄復制了到了Tomcat中,現在的狀態是:

       服務器上的StreamingAssets內容和安卓客戶的StreamingAssets內容是相同的。這種狀態下客戶端是不會進行更新操作的。

       假使安卓包已經上線,過了幾天,我們需要更新版本。

       更新內容就是:調整商店頁面的商品,將商品1進行更新。

現在制作一個新的商店頁面。

1)修改ShopPanel的預制體,將原商品1的名稱修改為“新品“,圖標也進行調整,如下圖:

    

2)執行Build Android Resource菜單,重新進行打包;

3)打包完成后,將StreamingAssets目錄復制到Tomcat的webapps目錄下,覆蓋掉之前的內容。

3、重新運行客戶端

       經過上一步的操作,現在的服務器資源是更新后的顯示為“新品”的資源,而客戶而還是之前的顯示為“商品1”的資源。如下圖:

 

在商店資源更新到服務器后,不用重新打安卓包。

直接重新運行之前的安卓客戶端 ,如果客戶端打開商店顯示了“新口”的商品,則說明資源熱更新成功了(預制體是一種Unity資源)。

好了,重新運行客戶端。

點擊商城按鈕。能看到,商店界面已經自動更新到服務器的版本了。

 

效果與預期的一致,資源熱更成功。

 

三、代碼熱更新

這里說的代碼熱更,只包含lua代碼,所有的c#代碼是沒法更新的。

所以c#代碼一般用來寫一此底層邏輯,以及通用型邏輯,具體的業務邏輯最好都由lua來實現。

在版本計划中,如果不得不改動c#代碼,那就只能發個全量包了。

現在開始做代碼熱更。

計划:修改ShopPanel.lua的代碼,在代碼中動態修改商店界面的標題,如果能看到商店標題被更改,則表示代碼熱更成功。

1、  修改ShopPanel.lua的代碼,在代碼中引用標題所在的Text組件,並將商店標題修改為“熱更商店”。具體修改見下圖:  

2、  點擊Build Android Resource,重新生成打包資源;

3、  將StreamingAssets目錄復制到Tomcat的webapps目錄,覆蓋掉之前的;

4、  重新運行客戶端程序。

能看到商店的標題已經被修改了。

 

說明代碼更新成功。

 

至此,熱更操作實戰演練完成。

 

一些說明:

  1. 本文選用安卓包做客戶端,一是為了驗證這個熱更功能在移動端上的可用性;二是因為,這個資源熱更功能在Windows平台無法正常加載更新的資源。可能是框架原因,也可能是我的疏漏,沒有查證。 不過好在安卓平台上的熱更是沒有問題的。至於iOS平台,條件有限,沒法去測試。
  2.  熱更版本的包在第一次啟動的時候,有一個漫長的解壓縮過程,上一篇講原理的時候,有提到過。直接表現就是第一次運行,會黑屏很久。我這里沒有黑屏,是因為我的大廳面板是直接顯示的,不用等待解壓過程。 但是,一看到大廳界面,就立即點擊排行榜按鈕和商城按鈕,是不會在響應的,因為資源未解壓完成,lua腳本啥的還未加載。 我給工程加了一個Unity-Logs-Viewer插件,在屏幕上划2圈,能打開日志界面,從日志里能看到解壓縮的過程。
  3.  關於更新,目前框架實現的邏輯也比較簡單,直接比較files.txt的內容,發現不一致就進行更新。 如果是實際項目的話,要做版本控制:Tomcat的webapps目錄下應該是按版本放置的資源,並提供服務端版本號,客戶端要有取服務端版本信息的能力,並根據版本號,從不同的目錄讀取資源。
  4.  關於下載,目前的下載邏輯也比較簡易,是按資源一定能下載成功做的邏輯,沒有處理資源下載失敗等異常情況,最好在UI上也能對此過程有顯示,這個需要自己完善。
  5.  總的來說,這是一個可用的框架,但是還需要自己完善。

 

項目地址

為方便參照學習,本項目源碼已經上傳到github,地址:

https://github.com/tanyuqing/LuaFramework-in-action


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM