123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- using HybridCLR;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Threading.Tasks;
- using UnityEngine;
- using UnityEngine.Networking;
- public class LoadDll : MonoBehaviour
- {
- static LoadDll instance;
- private void Awake()
- {
- instance = this;
- }
- void Start()
- {
- StartCoroutine(DownLoadAssets(this.StartGame));
- }
- #region download assets
- private static Dictionary<string, byte[]> s_assetDatas = new Dictionary<string, byte[]>();
- public static byte[] ReadBytesFromStreamingAssets(string dllName)
- {
- return s_assetDatas[dllName];
- }
- private string GetWebRequestPath(string asset)
- {
- var path = $"{Application.streamingAssetsPath}/{asset}";
- if (!path.Contains("://"))
- {
- path = "file://" + path;
- }
- return path;
- }
- private static List<string> AOTMetaAssemblyFiles { get; } = new List<string>()
- {
- "mscorlib.dll.bytes",
- "System.dll.bytes",
- "System.Core.dll.bytes",
- };
- IEnumerator DownLoadAssets(Action onDownloadComplete)
- {
- var assets = new List<string>
- {
- "playsounds",
- "excel_buttom",
- "gongye",
- "prefabs",
- "cubetest",
- "HotUpdate.dll.bytes",
- }.Concat(AOTMetaAssemblyFiles);
- foreach (var asset in assets)
- {
- string dllPath = GetWebRequestPath(asset);
- Debug.Log($"start download asset:{dllPath}");
- UnityWebRequest www = UnityWebRequest.Get(dllPath);
- yield return www.SendWebRequest();
- #if UNITY_2020_1_OR_NEWER
- if (www.result != UnityWebRequest.Result.Success)
- {
- Debug.Log(www.error);
- }
- #else
- if (www.isHttpError || www.isNetworkError)
- {
- Debug.Log(www.error);
- }
- #endif
- else
- {
- // Or retrieve results as binary data
- byte[] assetData = www.downloadHandler.data;
- Debug.Log($"dll:{asset} size:{assetData.Length}");
- s_assetDatas[asset] = assetData;
- }
- }
- onDownloadComplete();
- }
- #endregion
- private static Assembly _hotUpdateAss;
- /// <summary>
- /// 为aot assembly加载原始metadata, 这个代码放aot或者热更新都行。
- /// 一旦加载后,如果AOT泛型函数对应native实现不存在,则自动替换为解释模式执行
- /// </summary>
- private static void LoadMetadataForAOTAssemblies()
- {
- /// 注意,补充元数据是给AOT dll补充元数据,而不是给热更新dll补充元数据。
- /// 热更新dll不缺元数据,不需要补充,如果调用LoadMetadataForAOTAssembly会返回错误
- ///
- HomologousImageMode mode = HomologousImageMode.SuperSet;
- foreach (var aotDllName in AOTMetaAssemblyFiles)
- {
- byte[] dllBytes = ReadBytesFromStreamingAssets(aotDllName);
- // 加载assembly对应的dll,会自动为它hook。一旦aot泛型函数的native函数不存在,用解释器版本代码
- LoadImageErrorCode err = RuntimeApi.LoadMetadataForAOTAssembly(dllBytes, mode);
- Debug.Log($"LoadMetadataForAOTAssembly:{aotDllName}. mode:{mode} ret:{err}");
- }
- }
- void StartGame()
- {
- // LoadMetadataForAOTAssemblies();
- /*
- #if !UNITY_EDITOR
- _hotUpdateAss = Assembly.Load(ReadBytesFromStreamingAssets("HotUpdate.dll.bytes"));
- #else
- _hotUpdateAss = System.AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "HotUpdate");
- #endif
- */
- _hotUpdateAss = Assembly.Load(LoadDll.ReadBytesFromStreamingAssets("HotUpdate.dll.bytes"));
- // Type entryType = _hotUpdateAss.GetType("Entry");
- // entryType.GetMethod("Start").Invoke(null, null);
- Run_InstantiateComponentByAsset();
- }
- private static void Run_InstantiateComponentByAsset()
- {
-
- // 通过实例化assetbundle中的资源,还原资源上的热更新脚本
- AssetBundle ab = AssetBundle.LoadFromMemory(LoadDll.ReadBytesFromStreamingAssets("gongye"));
- GameObject cube = ab.LoadAsset<GameObject>("gongye");
- instance.StartCoroutine(load(cube));
- }
- static IEnumerator load(GameObject cube)
- {
- yield return new WaitForSeconds(1f);
- GameObject.Instantiate(cube);
- }
- }
|