天天看點

Unity筆記之熱更新

需求:實作熱更新全流程。(代碼熱更、物體熱更)

本篇文章使用的是xlua來開發的。學習的是這位老哥的

步驟:

1:導入xlua

(1)首先xlua直接去hub上下過來(XLua)。

Unity筆記之熱更新

(2)解壓壓縮包。打開檔案夾,把Assets裡面的東西全部複制到自己工程的Assets檔案夾下。

Unity筆記之熱更新
Unity筆記之熱更新

這裡面的其他檔案夾是我自己建立的。

然後再把tools也拖到工程目錄裡面跟Assets同級。

Unity筆記之熱更新

到這裡,xlua環境就算弄好了(不學習、運作案例的話)。

下面就是官方案例運作了:

案例都在XLua下的Examples檔案夾裡面。

運作案例之前需要打開場景之後;

在菜單面闆找到并點選XLua——Generate Code(生成);

然後點選Hotfix Inject In Editor(注入unity編輯器,這樣才能在unity編輯器裡面運作成功);

最後就是點選運作就可以了。

2:搭建自己的遊戲場景并寫入邏輯

(1)建立一個場景取名Game并放到Scenes檔案夾下。

(2)在Game場景裡面建立一個Plane作為地闆,建立一個Cube作為遊戲物體。

(3)給Cube添加剛體元件(Rigidbody)和腳本控制(Cube.cs)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;

[Hotfix]//辨別
public class Cube : MonoBehaviour
{
    private Rigidbody _rigidbody;//定義元件

    void Start()
    {
        _rigidbody = GetComponent<Rigidbody>();//擷取元件
    }

   [LuaCallCSharp]//辨別
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.W))//控制
        {
            _rigidbody.AddForce(Vector3.up * 500);
        }
    }
}
           

(4)在工程檔案的同一層級建立一個Lua檔案夾,并在Lua檔案夾下建立兩個文本檔案(取名Test.lua.txt和LuaDispose.lua.txt)

輸入内容

Test.lua.txt 的内容

local UnityEngine=CS.UnityEngine
xlua.hotfix(CS.Cube,'Update',function(self)
    if(UnityEngine.Input.GetKeyDown(UnityEngine.KeyCode.S))then
    self._rigidbody:AddForce(UnityEngine.Vector3.up*500)
    end

end)
           

LuaDispose.lua.txt 的内容

(5)建立一個熱更腳本(HotfixScript.cs)并在場景中建立一個空物體取名HotfixScript,把腳本拖到空物體上。

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
using XLua;

public class HotFixScript : MonoBehaviour
{
    private LuaEnv _luaEnv;//建立lua運作環境

    private void Awake()
    {
        _luaEnv = new LuaEnv(); //執行個體lua運作環境
        _luaEnv.AddLoader(MyLoader); //必須要有的
        _luaEnv.DoString("require'Test'"); //loader進行加載Test.lua.txt  從"E:\Test\Lua\" + filePath + ".lua.txt"檔案中進行加載 (注:require是固定不變的,調用完才能取得裡面的變量)
    }

    private byte[] MyLoader(ref string filePath)
    {
        string absPath = @"F:\XLua\Lua\" + filePath + ".lua.txt";
        return Encoding.UTF8.GetBytes(File.ReadAllText(absPath));
    }

    void Start()
    {
    }

    void Update()
    {
    }

    private void OnDisable()
    {
        _luaEnv.DoString("require'LuaDispose'"); //執行LuaDispose裡面的關閉方法
    }

    private void OnDestroy()
    {
        _luaEnv.Dispose(); //釋放lua環境
    }
}
           

然後就可以生成——注入——運作了。(到這裡第一個更新檔就完成了)

3:建立熱更資源并打出AB包

打ab包我之前的一篇部落格裡面有三種方法,随便選一種即可。

這裡我用的是AssetBundle Browser打包的。

打出ab包之後全選複制到伺服器檔案夾下的AssetBundles檔案夾裡面(我打的有兩個物體)

Unity筆記之熱更新

4:搭建一個簡單的本地伺服器

本地伺服器我有一篇部落格也寫到過。

這裡我用的是NetBox2的方法。

5:從伺服器上下載下傳AssetBundles,并加載出來

HotFixScript.cs腳本内容更新一下從伺服器上下載下傳AssetBundles,并加載出來的内容。

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
using XLua;

public class HotFixScript : MonoBehaviour
{
    private LuaEnv _luaEnv;//建立lua運作環境

    private void Awake()
    {
        _luaEnv = new LuaEnv(); //執行個體lua運作環境
        _luaEnv.AddLoader(MyLoader); //必須要有的
        _luaEnv.DoString("require'Test'"); //loader進行加載Test.lua.txt  從"E:\Test\Lua\" + filePath + ".lua.txt"檔案中進行加載 (注:require是固定不變的,調用完才能取得裡面的變量)
    }

    private byte[] MyLoader(ref string filePath)
    {
        string absPath = @"F:\XLua\Lua\" + filePath + ".lua.txt";
        return Encoding.UTF8.GetBytes(File.ReadAllText(absPath));
    }

    void Start()
    {
    }

    void Update()
    {
    }

    private void OnDisable()
    {
        _luaEnv.DoString("require'LuaDispose'"); //執行LuaDispose裡面的關閉方法
    }

    private void OnDestroy()
    {
        _luaEnv.Dispose(); //釋放lua環境
    }

    [LuaCallCSharp]//需要熱更腳本裡面調用的方法必須加上這個标簽
    public void LoadResource(string resName, string filePath) //開啟加載assetbundle裡面的資源的協程
    {
        StartCoroutine(Load(resName, filePath));
    }

    private Dictionary<string, GameObject> _objectsAssetBundleDic = new Dictionary<string, GameObject>();//把加載出來的AssetBundle物體存起來,友善使用的時候調用
    private string serverPath = @"http://localhost/AssetBundles"; //伺服器AssetBundles存放位址

    IEnumerator Load(string resName, string filePath)//加載assetbundle裡面的資源
    {
        UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(serverPath + filePath);
        yield return request.SendWebRequest();
        AssetBundle ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
        GameObject go = ab.LoadAsset<GameObject>(resName);
        Debug.Log(go.name);
        _objectsAssetBundleDic.Add(resName, go);
    }

    [LuaCallCSharp]//需要熱更腳本裡面調用的方法必須加上這個标簽
    public GameObject GetAssetBundlePrefab(string resName)//擷取到AssetBundle物體
    {
        return _objectsAssetBundleDic[resName];
    }
}
           

建立一個熱更加載代碼(Load.cs),以便通過lua調用C#裡面的方法。

using System;
using UnityEngine;
using XLua;

[Hotfix]
public class Load : MonoBehaviour
{
    public HotFixScript hot;//定義HotFixScript腳本

    private void Start()
    {
    }

    private void Update()
    {
        
    }
}
           

然後更新一下Test.lua.txt 和 LuaDispose.lua.txt 的内容

Test.lua.txt

local UnityEngine=CS.UnityEngine
xlua.hotfix(CS.Cube,'Update',function(self)
    if(UnityEngine.Input.GetKeyDown(UnityEngine.KeyCode.S))then
    self._rigidbody:AddForce(UnityEngine.Vector3.up*500)--(Lua裡面調用靜态方法直接”.“就可以了,非靜态方法得用”:“)
    end

end)

xlua.hotfix(CS.Load,'Start',function(self)--重寫Load代碼裡面的Start方法
    self.hot:LoadResource('capsule','\\capsule')--加載ab包裡面的capsule
self.hot:LoadResource('sphere','\\sphere')--加載ab包裡面的sphere
end)

xlua.hotfix(CS.Load,'Update',function(self)--重寫Load代碼裡面的Update方法

    if(UnityEngine.Input.GetKeyDown(UnityEngine.KeyCode.G))then
        UnityEngine.Object.Instantiate( self.hot:GetAssetBundlePrefab('capsule'))--生成capsule
        UnityEngine.Object.Instantiate( self.hot:GetAssetBundlePrefab('sphere'))--生成sphere
end
end)
           

LuaDispose.lua.txt

xlua.hotfix(CS.Cube,'Update',nil)

xlua.hotfix(CS.Load,'Update',nil)
xlua.hotfix(CS.Load,'Start',nil)
           

然後開啟伺服器,運作就可以了。

6:下載下傳Lua并加載

(1)建立一個Init場景作為加下載下傳Lua檔案、配置檔案的過渡場景。

(2)建立一個腳本實作Lua檔案下載下傳(LoadLua.cs)

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;

public class LoadLua : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(Load());
    }

    public List<string> luaName = new List<string>(); //所有需要熱更的lua的名字
    private string severPath = @"http://localhost/"; //伺服器位址
    private string clientPath = @"F:\XLua\Lua\"; //用戶端lua儲存位址

    IEnumerator Load()//從伺服器上下載下傳熱更腳本(如果有變則下載下傳新的,沒變則不下載下傳)
    {
        for (int i = 0; i < luaName.Count; i++)
        {
            UnityWebRequest requset = UnityWebRequest.Get(severPath + luaName[i] + ".lua.txt");
            yield return requset.SendWebRequest();
            string str = requset.downloadHandler.text;//擷取lua的内容
            Debug.Log(str);

            File.WriteAllText(clientPath + luaName[i] + ".lua.txt", str);//寫入并存入本地
        }
        SceneManager.LoadScene(1);//下載下傳完跳轉到遊戲場景(Game)
    }
}
           

以上就是熱更新的整個流程了。

本文僅作為個人紀錄,如有問題請自行去bilibili上看教程。

繼續閱讀