【InjectFix】InjectFix熱修復的使用


 
InjectFix可以看做XLua的升級版,能直接在unity工程上修改C#代碼即可更新,符合蘋果熱更新條款
 

一、原理:

虛擬機負責新邏輯的解析執行;注入代碼負責把調用重定向到虛擬機;
 

二、Demo使用流程和方法:

1.安裝
下載解壓后,VSProj文件夾下的built_for_unity.bat文件,編輯修改UNITY_HOME為本機unity安裝目錄,保存之后運行
 
IFixToolKit文件夾在和Asset文件夾同級目錄,Assets文件夾下有IFix和Plugins文件夾
 
打開之后可以看到:

 

Inject:注入,對工程進行一系列操作,保存當前狀態,Inject之后就不能生成補丁了
 Fix:生成一個熱修復文件,文件就是用來熱修復的,以.bytes結尾
 
2.配置熱更新
熱更新的實現依賴於提前做些靜態代碼插入,需要做配置類
而且配置必須打[Configure]標簽 必須放在Editor目錄下,創個腳本在Editor下
//兩種方式
//1、配置類必須打[Configure]標簽
//2、必須放Editor目錄
[Configure]
public class HelloworldCfg
{
    [IFix]
    private static IEnumerable<Type> hotfix
    {
        get
        {
            return new List<Type>()
            {
                typeof(Helloworld),
                typeof(IFix.Test.Calculator),
                //AnotherClass在Pro Standard Assets下,會編譯到Assembly-CSharp-firstpass.dll下,用來演示多dll的修復
                typeof(AnotherClass),
            };
        }
    }
    
    [IFix]
    private static IEnumerable<Type> ToProcess
    {
        get
        {
            return (from type in Assembly.Load("Assembly-CSharp").GetTypes()
                    where type.Namespace == "XLua" && !type.Name.Contains("<")
                    select type);
            //對XLua命名空間下進行插入
        }
    }
}

 

注:
*配置類打上Configure標簽
*配置的屬性打上IFix標簽,而且必須是 __static__ 類型
 
3.修改bug打補丁
如:
錯誤的代碼:
public int Add(int a, int b)
{
  return a - b;
}

在方法上打上[Patch]標簽並修改里面內容

[Patch]
public int Add(int a, int b)
{
    return a + b;
}

保存之后執行InjectFix/Fix菜單,在項目文件夾中生成.bytes文件

 

4.上傳補丁
實際項目可上傳到服務器中加載,在此仍然在原項目中使用,將Assembly-CSharp.patch.bytes文件放在Resources文件夾中。
 

更新:

三、在新項目中使用InjectFix

GitHub:https://github.com/caoweigang/InjectFixDemo

1.安裝InjectFix到新項目中:

 

 

 

1)下載示例代碼后,修改VSProj下的build_for_unity.bat文件,首行改為Unity的安裝目錄

 

2)運行build_for_unity.bat文件。

3)之后可以在UnityProj文件夾中看到 IFixToolKit文件夾,將此文件夾復制到項目的Assets的同級目錄

4)示例項目中的 IFix文件夾Plugins文件夾復制到項目的Assets文件夾下

2.配置類預處理代碼:

和xLua類似,熱補丁的實現依賴於提前做些靜態代碼插入,對熱更的類進行預處理。
兩種方式:指定類、指定命名空間下的所有類。
注意:配置文件必須添加[Configure]標簽,放在Editor文件夾下
[Configure]
public class MyConfig
{
    [IFix]
    private static IEnumerable<Type> ToProcess
    {
        get
        {
            return (from type in Assembly.Load("Assembly-CSharp").GetTypes()
                    where type.Namespace == "XXXXX" && !type.Name.Contains("<")
                    select type);
        }
    }
}
    [IFix]
    private static IEnumerable<Type> hotfix
    {
        get
        {
            return new List<Type>()
            {
                typeof(HotFixMgr),
                typeof(MyGame.TestScr),
                //AnotherClass在Pro Standard Assets下,會編譯到Assembly-CSharp-firstpass.dll下,用來演示多dll的修復
                //typeof(AnotherClass),
            };
        }
    }
過濾:
  [IFix.Filter]
    private static bool Filter(System.Reflection.MethodInfo methodInfo)
    {
        return methodInfo.DeclaringType.FullName == "IFix.Test.Calculator"
            && (methodInfo.Name == "Div" || methodInfo.Name == "Mult");
    }

 

3.加載補丁文件Assembly-CSharp.patch代碼:

//在項目啟動時候加載補丁文件
private async void DownloadScriptFixPatch()
{
     //#if !UNITY_EDITOR
     var patch = Resources.Load<TextAsset>("Assembly-CSharp.patch");
     if (patch != null)
     {
        //UnityEngine.Debug.Log("loading Assembly-CSharp.patch ...");
        //var sw = Stopwatch.StartNew();
        PatchManager.Load(new MemoryStream(patch.bytes));
        //UnityEngine.Debug.Log("patch Assembly-CSharp.patch, using " + sw.ElapsedMilliseconds + " ms");
    }
    //#endif
    var patch = await AssetCacheService.Instance.LoadByteAssetFromServer("FIX/Assembly-CSharp.patch.bytes");
    if (patch != null)
    {
         PatchManager.Load(new MemoryStream(patch));
    }
}

4.生成補丁並使用的過程(僅修改方法,不添加屬性方法和類)

 1)在需要修改的方法打上[Patch]標簽

[Patch]
private void SetView()
{
     title.text = GetString();
     content.text = contentStr;
     bg.color = color;
}

2)修改過代碼之后使用InjectFix/Fix,生成Assembly-CSharp.patch補丁文件,即包含了當前修改內容。

3)上傳補丁文件到服務器
4)在Unity中模擬時放在Resource文件中,並且需要InjectFit/Inject

5.添加屬性、新增方法、新增類使用[Interpret]

private string name;//這個name字段是原生的

public string Name
{
    [IFix.Interpret]
    set
    {
        name = value;    
    }
    [IFix.Interpret]
    get
    {
        return name;
    }
}
        
        
[Interpret]
private string GetString()
{
     return "123";
}

[IFix.Interpret]
public class NewClass
{
    ...類中增加的方法也應打標簽
}

 

 

 

 

 

 


免責聲明!

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



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