using Assets.Game.Launcher.HotUpdateProxy; using ET; using FairyGUI; using System; using System.Collections.Generic; using UnityEngine; namespace GFGGame.HotUpdate { public class HotUpdateEntry { public static void Start() { Log.Debug("HotUpdateEntry Start 1"); #if !UNITY_EDITOR LoadMetadataForAOTAssembly(); #endif Log.Debug("HotUpdateEntry Start 2"); VEngine.Logger.Loggable = false; //ET try { HotUpdateProxy.Instance.update = Game.Update; HotUpdateProxy.Instance.lateUpdate = Game.LateUpdate; HotUpdateProxy.Instance.onApplicationQuit = Game.Close; Game.EventSystem.Add(HotUpdateCodeLoader.Instance.GetTypes()); Game.EventSystem.Publish(new ET.EventType.AppStart()); } catch (Exception e) { Log.Error(e); } Log.Debug("HotUpdateEntry Start 3"); GameController.Start(); Log.Debug("HotUpdateEntry Start 4"); } /// /// 为aot assembly加载原始metadata, 这个代码放aot或者热更新都行。 /// 一旦加载后,如果AOT泛型函数对应native实现不存在,则自动替换为解释模式执行 /// public static unsafe void LoadMetadataForAOTAssembly() { // 可以加载任意aot assembly的对应的dll。但要求dll必须与unity build过程中生成的裁剪后的dll一致,而不能直接使用原始dll。 // 我们在BuildProcessor_xxx里添加了处理代码,这些裁剪后的dll在打包时自动被复制到 {项目目录}/HybridCLRData/AssembliesPostIl2CppStrip/{Target} 目录。 /// 注意,补充元数据是给AOT dll补充元数据,而不是给热更新dll补充元数据。 /// 热更新dll不缺元数据,不需要补充,如果调用LoadMetadataForAOTAssembly会返回错误 /// List aotDllList = new List { "mscorlib.dll", "System.dll", "System.Core.dll", // 如果使用了Linq,需要这个 "ThirdParty.dll", "Game.Launcher.dll", // "Newtonsoft.Json.dll", // "protobuf-net.dll", // "Google.Protobuf.dll", // "MongoDB.Bson.dll", // "DOTween.Modules.dll", // "UniTask.dll", }; foreach (var aotDllName in aotDllList) { byte[] dllBytes = GFGAsset.Load($"{LauncherConfig.DllDirAOT}{aotDllName}.bytes").bytes; fixed (byte* ptr = dllBytes) { // 加载assembly对应的dll,会自动为它hook。一旦aot泛型函数的native函数不存在,用解释器版本代码 int err = HybridCLR.RuntimeApi.LoadMetadataForAOTAssembly((IntPtr)ptr, dllBytes.Length); Debug.Log($"LoadMetadataForAOTAssembly:{aotDllName}. ret:{err}"); } } } } }