Unity热更新笔记(三)Addressable+ILRuntime 实现代码热更

本文档介绍了如何将ILRuntime的DLL转换为Addressables支持的资源格式,以实现在Unity中的热更新。流程包括DLL转成.bytes文件,使用TextAsset加载,并通过Addressables进行异步加载。此外,还提供了DLL转换和加载的代码示例。

系列文章目录

(一)ILRuntime基础使用
(二)Addressable基础使用



简介

把热更项目的 DLL 作为 addressable 的资源来实现热更新


流程

  • 资源部分
    (1)addressable 是不支持 dll 的,所以需要把 dll 文件加工成 addressable 支持的格式
    (2)直接 File.ReadAllBytes 读取成 bytes 然后 File.WriteAllBytes 保存
    (3)保存文件的后缀为 .bytes (.txt 被会被转换成 UTF-8 编码导致加载出来跟源文件不符)
    (4)然后是正常的资源热更新
  • DLL 加载
    (1)使用 TextAsset 类型加载文件
    (2)TextAsset.bytes 拿到需要的 byte[]
    (3)后续就是正常的 ILRuntime 初始化了

DLL 转换代码

    [MenuItem("MyMenu/ILRuntime/DLL To byte[]")]
    public static void DLLToBytes()
    {
        DLLToBytes(true);
    }
    [MenuItem("MyMenu/ILRuntime/DLL To byte[] (Choose Folder)")]
    public static void DLLToBytes_Choose()
    {
        DLLToBytes(false);
    }
    
    private static void DLLToBytes(bool autoChoosePath)
    {
        string folderPath;
        if (autoChoosePath)
            folderPath = NormalPath;
        else
                folderPath= EditorUtility.OpenFolderPanel("选择 DLL 所在的文件夹", Application.dataPath + "/Addressable/ILRuntime", string.Empty);
        if (string.IsNullOrEmpty(folderPath)) return;

        DirectoryInfo directoryInfo = new DirectoryInfo(folderPath);
        if (directoryInfo == null) return;

        FileInfo[] fileInfos = directoryInfo.GetFiles();

        List<FileInfo> listDLL = new List<FileInfo>();
        List<FileInfo> listPDB = new List<FileInfo>();

        for (int i = 0; i < fileInfos.Length; i++)
        {
            if (fileInfos[i].Extension == ".dll")
            {
                listDLL.Add(fileInfos[i]);
            }
            else if (fileInfos[i].Extension == ".pdb")
            {
                listPDB.Add(fileInfos[i]);
            }
        }

        if (listDLL.Count + listPDB.Count <= 0)
        {
            Debug.Log("文件夹下没有dll文件");
            return;
        }
        else
        {
            Debug.Log("选择路径为:" + folderPath);
        }

        string savePath;
        if (autoChoosePath)
            savePath = NormalPath;
        else
            savePath = EditorUtility.OpenFolderPanel("选择 DLL 转换后保存的文件夹", Application.dataPath + "/Addressable/ILRuntime", string.Empty);
        if (string.IsNullOrEmpty(savePath)) return;

        Debug.Log("---开始转换 DLL 文件------------------");
        string path = string.Empty;
        for (int i = 0; i < listDLL.Count; i++)
        {
            path = $"{savePath}/{Path.GetFileNameWithoutExtension(listDLL[i].Name)}_dll_res.bytes";
            BytesToFile(path, FileToBytes(listDLL[i]));
        }
        Debug.Log("---DLL 文件转换结束------------------");

        Debug.Log("---开始转换 PDB 文件------------------");
        for (int i = 0; i < listPDB.Count; i++)
        {
            path = $"{savePath}/{Path.GetFileNameWithoutExtension(listPDB[i].Name)}_pdb_res.bytes";
            BytesToFile(path, FileToBytes(listPDB[i]));
        }
        Debug.Log("---PDB 文件转换结束------------------");
        Debug.Log("导出路径为:" + savePath);

        AssetDatabase.Refresh();
    }

    private static byte[] FileToBytes(FileInfo fileInfo)
    {
        return File.ReadAllBytes(fileInfo.FullName);
    }
    private static void BytesToFile(string path, byte[] bytes)
    {
        Debug.Log($"Path:{path}\nlength:{bytes.Length}");
        File.WriteAllBytes(path, bytes);
    }

DLL 加载代码

        private static byte[] LoadFile(string path)
        {
            Debug.Log(path);
            return System.IO.File.ReadAllBytes(path);
        }
        private static async Task<byte[]> LoadFile_Addressables(string path)
        {
            Debug.Log(path);
            var text= await Addressables.LoadAssetAsync<TextAsset>(path).Task;
          
            return text.bytes;
        }
        private static async Task<byte[]> LoadFile_WebRequest(string path)
        {
            var request = UnityWebRequest.Get("file:///" + DLLPath_File );
            request.SendWebRequest();
            while (!request.isDone)
                await Task.Delay(200);
            if (!string.IsNullOrEmpty(request.error))
                Debug.LogError(request.error);
            byte[] bytes = request.downloadHandler.data;
            //销毁请求对象
            request.Dispose();

            return bytes;
        }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值