跳至主要内容
版本:v3

Hotfixers

重要 注意 提醒

Coding Style wiki​


Hotfixers 是 Hotfixer 模組的統一呼叫入口(Facade),整合 HybridCLR 程式碼熱更新方案,涵蓋熱更新流程檢查(下載與載入)、AOT 元數據補充、Hotfix DLL 載入與狀態查詢。

命名空間OxGFrame.Hotfixer
類型public static class
原始碼Hotfixers.cs
using OxGFrame.Hotfixer;

提醒 使用 HybridCLR 如有疑問,請前往官方文件進行熟悉;完整使用流程可參考 HotfixerDemo(從 Package Manager 匯入)。

快速上手​

// 啟動熱更新流程(自動讀取 StreamingAssets 中的 HotfixManifest.dat 配置檔)
Hotfixers.CheckHotfix("HotfixPackage");

// 等待熱更新完成,再進入遊戲主邏輯與資源更新
await UniTask.WaitUntil(() => Hotfixers.IsDone());

// 主程式集無法直接引用熱更層,透過反射呼叫熱更代碼
var assembly = Hotfixers.GetHotfixAssembly("HotfixerDemo.Hotfix.Runtime.dll");
assembly?.GetType("Hello")?.GetMethod("Run")?.Invoke(null, null);

通用規則​

核心機制​

Hotfixers 主要與 HybridCLR 整合,負責在運行時:

  1. 補充 AOT 元數據:解決 AOT 泛型實例化等問題(透過 RuntimeApi.LoadMetadataForAOTAssembly,採 HomologousImageMode.SuperSet 模式)。
  2. 載入熱更新 DLL:以 Assembly.Load 將更新後的程式邏輯載入至執行環境。

重要 主程式集(AOT)無法直接引用熱更新程式集。熱更載入完成後,需透過反射呼叫熱更層代碼(可由 GetHotfixAssembly 取得程式集)。

提醒 AOT / Hotfix DLL 需先透過 Editor 工具 HotfixHelper 收集(.dll.bytes),再以 YooAsset 打包至 Hotfix Package 中,收集方式請參考收集示例。

熱更流程​

呼叫 CheckHotfix 後,內部狀態機將依序執行以下流程:

順序流程狀態說明
1FsmHotfixPrepare流程準備。
2FsmInitHotfixPackage初始化 Hotfix Package;失敗時發送 HotfixInitFailed 事件。
3FsmUpdateHotfixPackage更新 Hotfix Package 版本;失敗時發送 HotfixUpdateFailed 事件。
4FsmHotfixCreateDownloader建立下載器。有待下載檔案時,發送 HotfixCreateDownloader 事件並等待使用者確認;無則直接進入下載完成。
5FsmHotfixBeginDownload開始下載;過程中發送 HotfixDownloadProgression 進度事件,下載失敗時發送 HotfixDownloadFailed 事件。
6FsmHotfixDownloadOver下載完成。
7FsmHotfixClearCache清理未使用的快取檔案。
8FsmLoadAOTAssemblies為 AOT 程式集補充元數據(HybridCLR RuntimeApi.LoadMetadataForAOTAssembly)。
9FsmLoadHotfixAssemblies載入熱更新程式集(Assembly.Load)。
10FsmHotfixDone流程完成,IsDone 回傳 true。
注意
  • 有檔案待下載時,流程會停在步驟 4,需由使用者發送 UserBeginDownload 事件確認後才會開始下載(參考流程事件)。
  • DLL 檔案將以清單中的名稱(含 .dll)作為資源名稱,從 Hotfix Package 以 TextAsset 形式載入,載入完成後隨即卸載。
  • 編輯器模擬模式(EditorSimulateMode)下會跳過 AOT 元數據補充;於 Editor 或熱更停用時,熱更程式集改由目前 AppDomain 直接查找(不實際載入 DLL bytes)。

配置檔 HotfixManifest.dat​

自動配置模式的 CheckHotfix 多載,會向 StreamingAssets 請求熱更新配置檔,並依配置內容啟動流程:

  • 檔名預設為 HotfixManifest.dat,可透過 HotfixSettings 自訂名稱與副檔名(參考全局配置)。
  • 內容包含 aotDlls 與 hotfixDlls 兩組清單(名稱皆含 .dll 副檔名),支援明文 JSON 與加密 BYTES 兩種格式,讀取時依檔頭自動判別。
  • 可透過 HotfixHelper.ExportHotfixDllConfig 或編輯器選單 OxGFrame → Hotfixer → Hotfix Config Generator (HotfixManifest.dat) 視窗工具產生。

明文 JSON 格式內容如下:

{
"aotDlls": [
"mscorlib.dll",
"UniTask.dll"
],
"hotfixDlls": [
"HotfixerDemo.Hotfix.Runtime.dll"
]
}

流程事件​

熱更流程透過 UniEvent(UniFramework.Event)廣播與接收事件,事件定義於命名空間 OxGFrame.Hotfixer.HotfixEvent。

框架發送(HotfixEvents)— 由使用者監聽

事件說明
HotfixFsmState流程狀態切換通知,攜帶當前狀態節點 stateNode。
HotfixInitFailedHotfix Package 初始化失敗。
HotfixUpdateFailedHotfix Package 版本更新失敗。
HotfixCreateDownloader下載器建立完成,攜帶待下載檔案數 totalCount 與總大小 totalBytes。
HotfixDownloadProgression下載進度,攜帶 progress、下載數量、大小與速度等資訊。
HotfixDownloadFailed檔案下載失敗,攜帶 fileName 與 error。

使用者發送(HotfixUserEvents)— 驅動流程繼續

事件說明
UserTryInitHotfix重新嘗試初始化 Hotfix Package。
UserTryUpdateHotfix重新嘗試更新 Hotfix Package。
UserTryCreateDownloader重新嘗試建立下載器。
UserBeginDownload確認開始下載熱更新檔案。
using OxGFrame.Hotfixer.HotfixEvent;
using UniFramework.Event;

// 監聽下載器建立完成事件,確認後開始下載
UniEvent.AddListener<HotfixEvents.HotfixCreateDownloader>((message) =>
{
var msgData = message as HotfixEvents.HotfixCreateDownloader;
Debug.Log($"待下載檔案數:{msgData.totalCount},總大小:{msgData.totalBytes}");
HotfixUserEvents.UserBeginDownload.SendEventMessage();
});

停用熱更新​

重要 若停用 HybridCLR(HybridCLR Settings 取消勾選 Enable),必須搭配巨集 OXGFRAME_HYBRIDCLR_DISABLED,才能有效剔除熱更流程。

定義巨集後 IsDisabled 將回傳 true,流程將跳過 AOT 元數據補充,熱更程式集改由目前 AppDomain 直接查找。

方法總覽​

熱更流程檢查​

方法說明
CheckHotfix啟動熱更新流程,下載並載入所有熱更新相關檔案。

狀態與重置​

方法說明
IsDone回傳熱更新流程是否已全部完成。
IsDisabled回傳熱更新功能是否已停用。
Reset重置熱更新標記與快取資料。

程式集資訊​

方法說明
GetAOTAssemblyNames取得 AOT 程式集名稱(含 .dll 副檔名)。
GetAotAssemblyNamesWithoutExtensions取得 AOT 程式集名稱(不含副檔名)。
GetHotfixAssemblyNames取得熱更新程式集名稱(含 .dll 副檔名)。
GetHotfixAssemblyNamesWithoutExtensions取得熱更新程式集名稱(不含副檔名)。
GetHotfixAssembly依名稱取得已載入的 Assembly 物件。

CheckHotfix​

public static void CheckHotfix(string packageName, Action errorAction = null)
public static void CheckHotfix(PackageInfoWithBuild packageInfoWithBuild, Action errorAction = null)
public static void CheckHotfix(string packageName, string[] aotAssemblies, string[] hotfixAssemblies)
public static void CheckHotfix(PackageInfoWithBuild packageInfoWithBuild, string[] aotAssemblies, string[] hotfixAssemblies)

參數

參數型別說明
packageNamestringHotfix 資源包名稱。
packageInfoWithBuildPackageInfoWithBuild自訂的資源包資訊(可自行指定建置模式等,命名空間 OxGFrame.AssetLoader.Bundle)。
errorActionAction配置檔請求失敗(URL 無效、請求錯誤或逾時)、內容為空或解析失敗時觸發的回呼。
預設值:null
aotAssembliesstring[]需補充元數據的 AOT 程式集清單(名稱含 .dll 副檔名)。
hotfixAssembliesstring[]熱更新程式集清單(名稱含 .dll 副檔名)。

說明

啟動熱更新流程,開始下載並載入所有熱更新相關檔案,完整流程參考熱更流程。多載分為兩種模式:

  • 自動配置模式(errorAction 多載):自動向 StreamingAssets 請求 HotfixManifest.dat 配置檔(參考配置檔),解析出 AOT 與 Hotfix 程式集清單後啟動流程。
  • 手動指定模式(aotAssemblies 多載):直接傳入需補充元數據的 AOT 程式集與熱更新程式集清單。
注意
  • 此方法為非阻塞呼叫,完成與否需透過 IsDone 或流程事件判斷。
  • 僅指定 packageName 的多載,將以 AppPackageInfoWithBuild(建置模式 ScriptableBuildPipeline)初始化 Package;如需自訂建置模式,請改用 PackageInfoWithBuild 多載。
  • 流程進行中重複呼叫將被忽略(輸出警告)。
  • 流程已完成後再次呼叫將直接返回(輸出警告),需先呼叫 Reset 才能重新執行。

範例

// 自動配置模式:讀取 StreamingAssets 中的 HotfixManifest.dat
Hotfixers.CheckHotfix
(
"HotfixPackage",
() => Debug.LogWarning("配置檔請求失敗,請先產生 HotfixManifest.dat")
);

// 手動指定模式:直接傳入 AOT 與 Hotfix 程式集清單
Hotfixers.CheckHotfix
(
"HotfixPackage",
// 需補充元數據的 AOT 程式集
new string[] { "mscorlib.dll", "UniTask.dll" },
// 熱更新程式集
new string[] { "HotfixerDemo.Hotfix.Runtime.dll" }
);

IsDone​

public static bool IsDone()

回傳值

bool — 熱更新流程是否已全部完成(下載與載入皆完成後為 true)。

說明

回傳熱更新完成狀態。建議等待此狀態為 true 後,再進入遊戲主邏輯與資源更新。

範例

Hotfixers.CheckHotfix("HotfixPackage");

// 等待熱更新完成
await UniTask.WaitUntil(() => Hotfixers.IsDone());

// 進入遊戲主流程

IsDisabled​

public static bool IsDisabled()

回傳值

bool — 是否已停用熱更新功能;專案定義 OXGFRAME_HYBRIDCLR_DISABLED 巨集時回傳 true。

說明

檢查當前環境是否停用了熱更新功能(由編譯期巨集決定,通常用於開發者模式)。

重要 若停用 HybridCLR,必須搭配巨集 OXGFRAME_HYBRIDCLR_DISABLED,才能有效剔除熱更流程(參考停用熱更新)。


Reset​

public static void Reset()

說明

重置熱更新的標記與快取資料(包含完成標記、已記錄的 AOT / Hotfix 程式集名稱與已載入的 Assembly 快取),使 CheckHotfix 能重新執行。

提醒 重置後重新載入熱更 DLL 屬於 HotReload 範疇,需 HybridCLR 商業版支援才可使用(社群版不支援)。


GetAOTAssemblyNames​

public static string[] GetAOTAssemblyNames()

回傳值

string[] — AOT 程式集名稱陣列(含 .dll 副檔名);尚未執行過 CheckHotfix 時回傳 null。

說明

取得需補充元數據的 AOT 程式集名稱清單。此清單於呼叫 CheckHotfix 時設定。


GetAotAssemblyNamesWithoutExtensions​

public static string[] GetAotAssemblyNamesWithoutExtensions()

回傳值

string[] — 去除 .dll 副檔名的 AOT 程式集名稱陣列;尚未執行過 CheckHotfix 時回傳 null。

說明

同 GetAOTAssemblyNames,但名稱不含 .dll 副檔名(首次呼叫時轉換並快取結果)。


GetHotfixAssemblyNames​

public static string[] GetHotfixAssemblyNames()

回傳值

string[] — 熱更新程式集名稱陣列(含 .dll 副檔名);尚未執行過 CheckHotfix 時回傳 null。

說明

取得熱更新程式集名稱清單。此清單於呼叫 CheckHotfix 時設定。


GetHotfixAssemblyNamesWithoutExtensions​

public static string[] GetHotfixAssemblyNamesWithoutExtensions()

回傳值

string[] — 去除 .dll 副檔名的熱更新程式集名稱陣列;尚未執行過 CheckHotfix 時回傳 null。

說明

同 GetHotfixAssemblyNames,但名稱不含 .dll 副檔名(首次呼叫時轉換並快取結果)。


GetHotfixAssembly​

public static Assembly GetHotfixAssembly(string assemblyName)

參數

參數型別說明
assemblyNamestring熱更新程式集名稱(含 .dll 副檔名,如 HotfixerDemo.Hotfix.Runtime.dll)。

回傳值

Assembly — 已載入的熱更新程式集;查無時回傳 null。

說明

依名稱取得已載入的 Assembly 物件。主程式集無法直接引用熱更新程式集,可透過此方法取得程式集後,以反射呼叫熱更層代碼。

範例

// 熱更完成後,透過反射進入熱更層入口
var assembly = Hotfixers.GetHotfixAssembly("HotfixerDemo.Hotfix.Runtime.dll");
assembly?.GetType("Hello")?.GetMethod("Run")?.Invoke(null, null);