[游戏开发][Unity]Assetbundle下载篇(1)热更前准备与下载AB包清单

这篇具有很好参考价值的文章主要介绍了[游戏开发][Unity]Assetbundle下载篇(1)热更前准备与下载AB包清单。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

打包与资源加载框架目录

正文

热更流程都不是固定的,每个人写的状态机也有所差别,但是一些必要步骤肯定不可能少,例如下载清单,对比版本,下载AB包,标记下载完成。我接下来的每一篇文章都是下载AB包的重要步骤,大概率是不能省略的。

检查沙盒路径是否存在

public static string MakePersistentLoadPath(string path)
{
#if UNITY_EDITOR
        // 注意:为了方便调试查看,编辑器下把存储目录放到项目里
        string projectPath = Path.GetDirectoryName(Application.dataPath).Replace("\\","/");
        projectPath = GetRegularPath(projectPath);
        return StringFormat.Format("{0}/Sandbox/{1}", projectPath, path);
#else
        return StringFormat.Format("{0}/Sandbox/{1}", Application.persistentDataPath, path);
#endif
}

检查下载临时目录是否存在

请注意,热更时下载AB包先下载到临时目录,之后再拷贝到沙盒目录

public static string MakeDownloadTempPath(string path)
{
#if UNITY_EDITOR
    string projectPath = Path.GetDirectoryName(Application.dataPath).Replace("\\", "/");
    projectPath = GetRegularPath(projectPath);
    return StringFormat.Format("{0}/Sandbox_Temp/{1}", projectPath, path);
#else
    return StringFormat.Format("{0}/Sandbox_Temp/{1}", Application.persistentDataPath, path);
#endif
}

路径都确认存在后,开始下载


前文有介绍过,生成的AB包清单长这个样子,把这个文件生成二进制bytes文件扔到服务器上去下载。

[游戏开发][Unity]Assetbundle下载篇(1)热更前准备与下载AB包清单,项目管理,unity,游戏开发,Powered by 金山文档

第一行是SVN版本号

第二行是AB包数量

从第三行开始是资源包信息,以=号分割开有效数据,分别是

MD5.unity3d = 资源路径 = 资源路径的HashId = 包体KB大小 = SVN版本号 = 启动热更模式

每一行数据封装了一个PatchElement类,代码在下文中

我们项目封装了一下UnityWebRequest,叫WebDataRequest,你不想封装直接用UnityWebRequest即可,WebDataRequest代码在后面有。

private IEnumerator DownLoad()
{
    // 解析APP里的补丁清单
    string filePath = AssetPathHelper.MakeStreamingLoadPath(PatchDefine.InitManifestFileName);
    string url = AssetPathHelper.ConvertToWWWPath(filePath);
    using (WebDataRequest downloader = new WebDataRequest(url))
    {
        yield return downloader.DownLoad();
        if (downloader.States == EWebRequestStates.Success) 
        {
            PatchHelper.Log(ELogLevel.Log, "Parse app patch manifest.");
            ParseAppPatchManifest(downloader.GetData());
        }
        else
        {
            throw new System.Exception($"Fatal error : Failed download file : {url}");
        }
    }
}

// 解析补丁清单文件相关接口
public void ParseAppPatchManifest(byte[] data)
{
    if (AppPatchManifest != null)
        throw new Exception("Should never get here.");
    AppPatchManifest = new PatchManifest(true);
    AppPatchManifest.Parse(data);
}

PatchManifest类是一个专门解析AB包清单的类,看代码也能知道,Parse方法的最终目的,就是把清单的每一行数据解析成PatchElement然后加入到字典中存起来等着下载时调用

/// <summary>
/// 补丁清单文件
/// </summary>
public class PatchManifest
{
    private bool _isParse = false;

    /// <summary>
    /// 资源版本号
    /// </summary>
    public int DllVersion { private set; get; }
    public int ResVersion { private set; get; }
    private bool IsInit = false;

    /// <summary>
    /// 所有打包文件列表
    /// </summary>
    public readonly Dictionary<string, PatchElement> Elements = new Dictionary<string, PatchElement>();

    public PatchManifest(bool isInit = false)
    {
        IsInit = isInit;
    }

    /// <summary>
    /// 解析数据
    /// </summary>
    public void Parse(byte[] data)
    {
        using (var ms = new MemoryStream(data))
        {
            using(var br = new BinaryReader(ms))
            {
                Parse(br);
            }
        }
    }

    public void ParseFile(string filePath)
    {
        using (var fs = File.OpenRead(filePath))
        {
            using (var br = new BinaryReader(fs))
            {
                Parse(br);
            }
        }
    }

    /// <summary>
    /// 解析数据
    /// </summary>
    public void Parse(BinaryReader br)
    {
        if (br == null)
            throw new Exception("Fatal error : Param is null.");
        if (_isParse)
            throw new Exception("Fatal error : Package is already parse.");

        _isParse = true;

        // 读取版本号            
        DllVersion = br.ReadInt32();
        ResVersion = br.ReadInt32();

        GameVersion.PatchResDesc = ResVersion + "   dllVer:" + DllVersion;
        int fileCount = br.ReadInt32();
        // 读取所有Bundle的数据
        for(var i = 0; i < fileCount; i++)
        {
            var ele = PatchElement.Deserialize(br, IsInit);
            if (Elements.ContainsKey(ele.Name))
                throw new Exception($"Fatal error : has same pack file : {ele.Name}");
            Elements.Add(ele.Name, ele);
        }
    }
}

PatchElement是AB包清单每一行数据的封装,PatchManifest的Parse里会循环创建一个Elements字典保存这些数据。

public class PatchElement
{
    /// <summary>
    /// 文件名称
    /// </summary>
    public string Name { private set; get; }

    /// <summary>
    /// 文件MD5
    /// </summary>
    public string MD5 { private set; get; }

    /// <summary>
    /// 文件版本
    /// </summary>
    public int Version { private set; get; }

    /// <summary>
    /// 文件大小
    /// </summary>
    public long SizeKB { private set; get; }

    /// <summary>
    /// 构建类型
    /// buildin 在安装包中
    /// ingame  游戏中下载
    /// </summary>
    public string Tag { private set; get; }

    /// <summary>
    /// 是否是安装包内的Patch
    /// </summary>
    public bool IsInit { private set; get; }

    /// <summary>
    /// 下载文件的保存路径
    /// </summary>
    public string SavePath;

    /// <summary>
    /// 每次更新都会先下载到Sandbox_Temp目录,防止下到一半重启导致逻辑不一致报错
    /// temp目录下的文件在重新进入更新流程时先校验md5看是否要跳过下载
    /// </summary>
    public bool SkipDownload { get; set; }


    public PatchElement(string name, string md5, int version, long sizeKB, string tag, bool isInit = false)
    {
        Name = name;
        MD5 = md5;
        Version = version;
        SizeKB = sizeKB;
        Tag = tag;
        IsInit = isInit;
        SkipDownload = false;
    }

    public void Serialize(BinaryWriter bw)
    {
        bw.Write(Name);
        bw.Write(MD5);
        bw.Write(SizeKB);
        bw.Write(Version);
        if (IsInit)
            bw.Write(Tag);
    }

    public static PatchElement Deserialize(BinaryReader br, bool isInit = false)
    {
        var name = br.ReadString();
        var md5 = br.ReadString();
        var sizeKb = br.ReadInt64();
        var version = br.ReadInt32();
        var tag = EBundlePos.buildin.ToString();
        if (isInit)
            tag = br.ReadString();
        return new PatchElement(name, md5, version, sizeKb, tag, isInit);
    }
}

下面是下载数据封装,本质还是 UnityWebRequest文章来源地址https://www.toymoban.com/news/detail-557554.html

public class WebDataRequest : WebRequestBase, IDisposable
{
    public WebDataRequest(string url) : base(url)
    {
    }
    public override IEnumerator DownLoad()
    {
        // Check fatal
        if (States != EWebRequestStates.None)
            throw new Exception($"{nameof(WebDataRequest)} is downloading yet : {URL}");

        States = EWebRequestStates.Loading;

        // 下载文件
        CacheRequest = new UnityWebRequest(URL, UnityWebRequest.kHttpVerbGET);
        DownloadHandlerBuffer handler = new DownloadHandlerBuffer();
        CacheRequest.downloadHandler = handler;
        CacheRequest.disposeDownloadHandlerOnDispose = true;
        CacheRequest.timeout = Timeout;
        yield return CacheRequest.SendWebRequest();

        // Check error
        if (CacheRequest.isNetworkError || CacheRequest.isHttpError)
        {
            MotionLog.LogWarning($"Failed to download web data : {URL} Error : {CacheRequest.error}");
            States = EWebRequestStates.Fail;
        }
        else
        {
            States = EWebRequestStates.Success;
        }
    }

    public byte[] GetData()
    {
        if (States == EWebRequestStates.Success)
            return CacheRequest.downloadHandler.data;
        else
            return null;
    }
    public string GetText()
    {
        if (States == EWebRequestStates.Success)
            return CacheRequest.downloadHandler.text;
        else
            return null;
    }
}

到了这里,关于[游戏开发][Unity]Assetbundle下载篇(1)热更前准备与下载AB包清单的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [游戏开发][Unity]Assetbundle打包与资源加载框架

    我会分三个篇章写整个框架分别是: AB打包篇 AB下载篇 AB加载篇 整个框架内容比较多,属于企业级方案,涉及到增量打包、打包策略、AB包下载、边玩边下、资源管理系统,资源加载系统等功能。 Unity小白看本系列文章可能比较吃力。如果我哪里写的不好,影响理解了,欢迎

    2024年02月13日
    浏览(37)
  • [游戏开发][Unity]Assetbundle打包篇(1)打包流程介绍

    打包与资源加载框架目录 先捋一下打AB包的整体思路,首先,Unity4.6版本之后就使用了全新的打包接口 无论是全新打包还是增量打包都是使用这个API,所以一切的一切,都要围绕这个API开始讲起。 该API有四个参数 string outputPath AssetBundleBuild[] builds BuildAssetBundleOptions assetBundle

    2024年02月10日
    浏览(28)
  • [游戏开发][Unity]Assetbundle打包篇(2)打包资源配置篇

    打包与资源加载框架目录 可视化配置的方式有很多种,Json、XML、以及Unity内置的ScriptableObject序列化 配置文件里要有哪些内容呢,很显然,最重要的就是目标文件路径,其次是权重类型,权重类型有:必要打包型、被引用打包型、忽略类型。为何会有忽略类型呢,是因为我们

    2024年02月09日
    浏览(27)
  • [游戏开发][Unity]Assetbundle打包篇(5)使用Manifest二次构建资源索引

    打包与资源加载框架目录 正文开始前,先把打包代码放过来,请注意,前面的代码已省略,自己去对比前面的文章。本篇文章从第一次执行打包代码开始。 第一次调用BuildPipeline.BuildAssetBundles打包API后(详见代码第七行),会返回AssetBundleManifest的引用, 【疑问】: BuildPipe

    2024年02月03日
    浏览(23)
  • 【游戏提取/超详细记录向】关于unity游戏的资源提取所需资源及方法简介(AssetBundle及libil2cpp.so等解密)

    方法一 :AssetStudio提取(仅针对ab包及.assets、.boundle和.unity3d未加密的情况下) 1.在我们拿到一个游戏的安装包时,首先会疑惑如何打开。下载bandzip Bandizip · Free zip, 7z, unzip, unrar Archiver · Fast and easy ,这是一款非常方便的解压缩工具。安装后右键apk-压缩文件预览,即可打开

    2023年04月15日
    浏览(28)
  • Unity 从服务器加载AssetBundle资源写入本地内存,并将下载保存的AB资源从本地内存加载至场景

    AB资源打包后有一个【目录文件】AssetBundle,他保存了所有AB资源的路径与名称, 通过aLLAssetBundleURL链接路径 组拼 从【目录文件】获得的AB资源的名字,然后再协程方法内编写相关代码,从而实现从服务器加载资源的功能。详细见代码。

    2024年02月13日
    浏览(28)
  • 【Unity】Unity开发微信小游戏(一)准备和了解工作

    0.Unity小游戏版本 如不使用此版本,则无法搜索到 InstantGame package 1.Unity插件:InstantGame package 此插件用于处理项目中的贴图、音频、网格、动画、场景等资源文件,保证小程序包体不会过大。 插件可以关联UOS服务,通过面板自动上传。 运行小程序后自动加载,不需要编写代码

    2024年02月04日
    浏览(65)
  • unity的学习,准备搞一款mmo小游戏,服务器和客户端从零学

    先学一下unity,mmo服务器框架到时候在学习一下,暂时服务器简单做一下 如代码所示,简单了解一下。 我个人感觉不要一个放在Awake函数中,一个放在Start中。因为这只适合两个脚本使用,如果多个脚本还是没有办法解决脚本执行的顺序。在这里设置脚本的执行顺序,添加进

    2023年04月21日
    浏览(34)
  • 为虚幻引擎开发者准备的Unity指南

    Unity 是全球使用最广泛的实时 3D 引擎,能够为所有开发者提供高质量的创作体验。 本文针对想要转 Unity 的虚幻引擎开发者,提供了详细的教程指引,帮助开发者快速熟悉 Unity 引擎。利用 Unity 引擎创作出高画质、低能耗的优质内容,并跨平台发布到任意主流平台,包括 App

    2024年02月04日
    浏览(44)
  • 【Unity使用addressables制作资源热更+实时动态热更基本记录】

    一、Addressables基础操作教程 1、下载Addressables插件 点击菜单Window / Package Manager,打开插件包管理界面,搜索addressables Addressables的打包方式其实也是AssetBundle格式,只是在此基础上做了一层封装,方便进行管理(比如打包、加载、依赖等)。而我们知道,没有加密的AssetBundle是

    2024年02月10日
    浏览(25)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包