1. 程式人生 > >Xlua熱更新筆記

Xlua熱更新筆記

成員方法:通過物件呼叫

靜態方法:通過類呼叫

static全域性的,靜態方法只能放在靜態方法中,普通方法生命週期小於靜態方法(全域性的)如協程不能在靜態方法中呼叫

***************************環境配置與匯入********************

  1. 匯入Xlua檔案到Unity工程
  2. 配置巨集定義:新增 HOTFIX_ENABLE 到 'Edit > Project Settings > Player > Other Settings > Scripting Define Symbols'。
    (注意:各平臺需要分別設定)
  3. 生成程式碼:執行 'XLua > Generate Code' 選單,等待Unity編譯完成。
  4. 注入:執行 'XLua > Hotfix Inject In Editor' 選單。注入成功會列印 'hotfix inject finish!' 或者 'had injected!' 。";
  5. 按提示匯入Tools資料夾,必須是英文路徑

*************************lua虛擬環境搭建*********************************

  1. using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using XLua;
    using System.IO;
    public class HotFixScript : MonoBehaviour {
        private LuaEnv LuaEnv;
    	// Use this for initialization
    	void Start () {
            //第一步
            LuaEnv = new LuaEnv();
            //第二步
            LuaEnv.AddLoader(MyLoader);
            //第三步 具體執行哪一個檔案
            LuaEnv.DoString("require'Fish'");       //lua命令
    	}
    	
    	// Update is called once per frame
    	void Update () {
    		
    	}
    
        //自定義Loader
    
        private byte[] MyLoader(ref string filePath)    //傳入檔案路徑
        {
            string absPath = @"E:\XluaPractice\FishingJoy\HotFixScripts\" + filePath + ".lua.txt";
    
            return System.Text.Encoding.UTF8.GetBytes( File.ReadAllText(absPath));   //讀取檔案
        }
    
        private void OnDestroy()
        {
            LuaEnv.Dispose();       //釋放虛擬環境
        }
    }
    

    建立的lua檔案

    print ('123')
    

    使用建議

  • 對所有較大可能變動的型別加上Hotfix標識;
  • 建議用反射找出所有函式引數、欄位、屬性、事件涉及的delegate型別,標註CSharpCallLua;
  • 業務程式碼、引擎API、系統API,需要在Lua補丁裡頭高效能訪問的型別,加上LuaCallCSharp;
  • 引擎API、系統API可能被程式碼剪裁調(C#無引用的地方都會被剪裁),如果覺得可能會新增C#程式碼之外的API呼叫,這些API所在的型別要麼加LuaCallCSharp,要麼加ReflectionUse;

*****************************************************************範例****************************************************************************

 

  1. 引入名稱空間 using XLua;
  2. 打標籤 [Hotfix]
  3. 如果Lua會用到C#裡的方法,需要在方法前加上[LuaCallCSharp]

*************************************************************改變一個私有型別的變數******************************************************

  1. 只賦值的時候不用打LuaCallCsharp標籤

**************************************************************補丁打在什麼位置********************************************************

  • Awake函式內
  • 如果在Start裡,那麼要更新Start函式就不會執行

******************************************************只修改方法體內部分程式碼************************************************

(先執行已有邏輯,在執行新加邏輯)

  1. 引入util檔案,定義為變數方便使用 local util=require 'util'--匯入庫檔案,類似引入名稱空間(平級目錄)
  2. 用util.hotfix_ex(CS.ClassName,'方法名',function(self)  Self.方法名(Self)    Self.屬性=???   end)呼叫
  3. 釋放時還是使用xlua.hotfix(CS.ClassName,'方法名',nil)

******************************************************************帶引數的方法**************************************************

  1. util.hotfix_ex(CS.ClassName,'方法名',function(self,引數名)  Self.方法名(Self,引數名)    函式體   end)
  2. --傳遞進來的引數不用加self

 

*************************************************************多過載函式***********************************************************

UnityEngine.Random.Range多過載函式回取到浮點型別可以用UnityEngine.Mathf.Floor向上或向下取整

*********************************************************在網路載入AB包*****************************************************

  1.  需要在協程中載入
  2. 靜態方法不能開啟協程
    using UnityEngine.Networking;
    
    public void LoadResource(string resName, string filePath) //第一個引數是想要載入的預製體的名字,第二個引數是想要載入的檔案路徑
        {
            StartCoroutine(LoadResourceCorotine(resName,filePath));
        }
    IEnumerator LoadResourceCorotine(string resName, string filePath)
        {
            //傳送請求
            UnityWebRequest request= UnityWebRequestAssetBundle.GetAssetBundle(@"http://localhost" + filePath);
            //下載到request物件裡
            yield return request.SendWebRequest();
            //下載到的內容
            
            AssetBundle ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
            GameObject gameObject = ab.LoadAsset<GameObject>(resName);
            //放到什麼地方
            prefabsDic.Add(resName, gameObject);
        }