XLua熱更新入門教程

什麼是XLua

XLua是騰訊開源的一款Unity熱更新插件

XLua與其他熱更新方案比優勢

  • GitHub上星數最多
  • 可以更多地使用C#代碼
  • Lua兼容多
  • 掌握Lua在遊戲行業更有競爭優勢

XLua熱更新流程

  • 把L和AB文件放在服務器上(這裏Lua腳本文件咱就叫L)
  • Unity應用從服務器下載L,L寫入在本地,編譯本地L,L內容是修改C#腳本內容,編譯修改後的C#腳本,哇,熱更了腳本
  • 再次熱更腳本,使C#腳本可以從服務器下載AB文件,把AB文件轉換成新遊戲對象(C#來寫Lua來調簡單些),有了對象,再次熱更腳本讓它在場景中顯示,哇,熱更了資源

教程環境

  • Unity2018.4.14f1
  • XLua最新版本
  • Win10家庭版64位1909

安裝過程

  • 打開自己某個Unity項目工程,該工程這裏咱取名叫B
  • 打開從GitHub下載的XLua,在B與之相對應目錄下拷入Xlua相關文件(如下圖)
    在這裏插入圖片描述
    在這裏插入圖片描述
  • Unity編輯打開PlayerSettings中的相關設置,其中鍵入”HOTFIX_ENABLE“(如下圖)
    在這裏插入圖片描述
  • 在B與之相對應目錄下,拷入3個Unity編輯器安裝目錄中的dll文件(如下圖)
    在這裏插入圖片描述
    在這裏插入圖片描述
  • 之後可運行XLua自帶案例試試,每次修改腳本後都要先點1再點3,只有代碼衝突才點2(如下圖)
    在這裏插入圖片描述
  • 在服務器上放3個Lua文件,1是補丁腳本,2是釋放腳本,3是XLua中的庫(如下圖)

在這裏插入圖片描述

開始寫代碼

  • 寫一個xlua熱更管理器腳本,把它掛載在某個遊戲對象上
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
using XLua;

[Hotfix] //所有要熱更的類都要打上這個標籤
public class HotFixScript : MonoBehaviour
{
    public static Dictionary<string, GameObject> prefabDict = new Dictionary<string, GameObject>(); //字典保存從AB文件加載的遊戲對象

    private LuaEnv luaEnv;

    private void Start()
    {
        luaEnv = new LuaEnv();
        luaEnv.AddLoader(MyLoader); //加載器方便加載而生,可以加載到該路徑下的一些lua文件
        luaEnv.DoString("require'fish2'"); //加載fish2
    }

    private byte[] MyLoader(ref string filepath)
    {
        var temp1 = Application.persistentDataPath; //本地可讀寫的目錄
        var temp2 = ".lua.txt";
        var temp3 = temp1 + "/" + filepath + temp2;
        return Encoding.UTF8.GetBytes(File.ReadAllText(temp3));
    }

    private void OnDisable()
    {
        luaEnv.DoString("require'fishDispose2'"); //加載fishDispose2,裏面有釋放的lua代碼
    }

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

    [LuaCallCSharp] //既然這個方法是要被Lua調用的,所以要加上這個標籤,性能更好,否則將會使用反射來搞性能更差
    public void LoadResource(string resName, string filePath) //從遠程加載ab轉換對象放入緩存,這裏是提前用C#寫好方法,然後用Lua去調用
    {
        StartCoroutine(LoadResourceCorotine(resName, filePath));
    }

    private IEnumerator LoadResourceCorotine(string resName, string filePath)
    {
        var request = UnityWebRequestAssetBundle.GetAssetBundle(@"http://122.51.186.74/Book/AssetBundles/" + filePath);
        yield return request.SendWebRequest();
        var ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
        var gameObject = ab.LoadAsset<GameObject>(resName);
        prefabDict.Add(resName, gameObject);
    }

    [LuaCallCSharp]
    public static GameObject GetGameObject(string goName) //獲取緩存的ab變成的對象
    {
        return prefabDict[goName];
    }
}
  • 上線版前放一個或多個腳本(如下),萬一上線版有新需求,就可以熱更新此腳本實現新類。
using UnityEngine;
using XLua;

[Hotfix]
public class HotClass2 : MonoBehaviour
{
    [LuaCallCSharp]
    public void Function1()
    {

    }

    [LuaCallCSharp]
    public void Function2()
    {

    }
}

  • 打AB資源包(略)
  • Lua釋放腳本(供參考)
xlua.hotfix(CS.Treasour,'CreatePrize',nil)--CS.Treasour表示類,'CreatePrize'表示類中方法,這裏要釋放掉
xlua.hotfix(CS.Bullect,'OnTriggerEnter',nil)
xlua.hotfix(CS.Bullect,'Start',nil)
xlua.hotfix(CS.CreateFish,'Update',nil)
xlua.hotfix(CS.CreateFish,'Start',nil)
  • Lua補丁腳本(供參考)
local UnityEngine=CS.UnityEngine 
local printTrue =true;
local util = require('util');

xlua.private_accessible(CS.Bullect)--開啓可以訪問私有成員
util.hotfix_ex(CS.Bullect,'OnTriggerEnter',function(self,other)--熱更方法,這個可以複寫原來方法,性能較差
	self.OnTriggerEnter(self,other)--原來的方法
	if printTrue then
             local go =UnityEngine.GameObject.Find("Ainiyou").GetComponent("Text");--沒有泛型用這種形式
             go.text = "ainiyou";             
	end
end)

xlua.hotfix(CS.Bullect,'Start',function(self)--熱更方法,這個是完全改寫
        local b = self:GetComponent('BoxCollider');
        print(b.isTrigger);
		local brandom =UnityEngine.Mathf.FloorToInt(UnityEngine.Random.Range(0,8));--Lua沒有int的解決方案
		print(brandom);
end)

util.hotfix_ex(CS.Treasour,'CreatePrize',function(self)

           self: CreatePrize();
	for i=0,4,1 do
		local go=UnityEngine.GameObject.Instantiate(self.gold,self.transform.position+UnityEngine.Vector3(-10+i*10,0,0),self.transform.rotation)--Vector3在Lua沒有New
		go.transform.SetParent(go.transform,self.cavas)
		local go1=UnityEngine.GameObject.Instantiate(self.diamands,self.transform.position+UnityEngine.Vector3(0,10,0)+UnityEngine.Vector3(-10+i*10,0,0),self.transform.rotation)
		go1.transform.SetParent(go1.transform,self.cavas)
	end
end)

xlua.private_accessible(CS.CreateFish)

xlua.hotfix(CS.CreateFish,'Start',function(self)
		self.hotFixScript:LoadResource('level3fish3','level3fish3.ab')--修改讓腳本可以加載ab
		--self.hotFixScript:LoadResource('SeaWave','gameobject\\wave.ab')
end)

補充說明

  • 個人一些配置,實現了給所有類打[HotFix](如下圖)
    在這裏插入圖片描述
  • 打安裝包要把XLua案例刪掉
  • 詳細教程請看官方文檔,水平有限,多多指教
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章