Unity 3D模型展示框架篇之资源打包、加载、热更(二)

这篇具有很好参考价值的文章主要介绍了Unity 3D模型展示框架篇之资源打包、加载、热更(二)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本项目将整合之前Unity程序基础小框架专栏在Unity 3D模型展示项目基础上进行整合,并记录了集成过程中对原脚本的调整过程。增加了Asset Bundle+ILRuntime热更新技术流程。

本篇文章介绍如何对更新进行代码检测以及使用更新资源服务器进行资源热更新。
创建登录UI预制体LoginUI.prefab,主要功能按钮如图所示:
Unity 3D模型展示框架篇之资源打包、加载、热更(二)添加项目启动脚本ProLaunch.cs,主要进行热更资源检测、下载更新操作。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.AddressableAssets.ResourceLocators;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class ProLaunch : MonoBehaviour
{

    /// <summary>
    /// 显示下载状态和进度
    /// </summary>
    public Text UpdateText;
    public Text DownText;

    public Button btnCheckAndUpdate;
    public Button btnUpdate;
    public Button btnDown;
    public Button btnLogin;
    public Slider Slider;//滑动条组件

    private List<object> _updateKeys = new List<object>();

    // Start is called before the first frame update
    void Start()
    {
        //retryBtn.gameObject.SetActive(false);
        btnCheckAndUpdate.onClick.AddListener(() =>
        {
            StartCoroutine(DoUpdateAddressadble());
        });
        btnUpdate.onClick.AddListener(() =>
        {
            UpdateCatalog();
        });
        // 默认自动执行一次更新检测
        //StartCoroutine(DoUpdateAddressadble());

        btnDown.onClick.AddListener(() =>
        {
            DownLoad();
        });

        btnLogin.onClick.AddListener(() =>
        {
            SceneManager.LoadScene(1);

            //StartCoroutine(LoadScene("Test2"));

        });
    }
    // Update is called once per frame
    void Update()
    { 
    }
    public async void UpdateCatalog()
    {
        //初始化Addressable
        var init = Addressables.InitializeAsync();
        await init.Task;

        //开始连接服务器检查更新
        var handle = Addressables.CheckForCatalogUpdates(false);
        await handle.Task;
        Debug.Log("check catalog status " + handle.Status);
        if (handle.Status == AsyncOperationStatus.Succeeded)
        {
            List<string> catalogs = handle.Result;
            if (catalogs != null && catalogs.Count > 0)
            {
                foreach (var catalog in catalogs)
                {
                    Debug.Log("catalog  " + catalog);
                }
                Debug.Log("download catalog start ");

                UpdateText.text = UpdateText.text + "\n下载更新catalog";
                var updateHandle = Addressables.UpdateCatalogs(catalogs, false);
                await updateHandle.Task;
                foreach (var item in updateHandle.Result)
                {
                    Debug.Log("catalog result " + item.LocatorId);

                    foreach (var key in item.Keys)
                    {
                        Debug.Log("catalog key " + key);
                    }
                    _updateKeys.AddRange(item.Keys);
                }
                Debug.Log("download catalog finish " + updateHandle.Status);

                UpdateText.text = UpdateText.text + "\n更新catalog完成" + updateHandle.Status;
            }
            else
            {
                Debug.Log("dont need update catalogs");
                UpdateText.text = "没有需要更新的catalogs信息";
            }
        }
        Addressables.Release(handle);

    }


    public void DownLoad()
    {
        StartCoroutine(DownAssetImpl());
    }

    public IEnumerator DownAssetImpl()
    {
        var downloadsize = Addressables.GetDownloadSizeAsync(_updateKeys);
        yield return downloadsize;
        Debug.Log("start download size :" + downloadsize.Result);
        UpdateText.text = UpdateText.text + "\n更新文件大小" + downloadsize.Result;

        if (downloadsize.Result > 0)
        {
            var download = Addressables.DownloadDependenciesAsync(_updateKeys, Addressables.MergeMode.Union);
            yield return download;
            //await download.Task;
            Debug.Log("download result type " + download.Result.GetType());
            UpdateText.text = UpdateText.text + "\n下载结果类型 " + download.Result.GetType();


            foreach (var item in download.Result as List<UnityEngine.ResourceManagement.ResourceProviders.IAssetBundleResource>)
            {
                var ab = item.GetAssetBundle();
                Debug.Log("ab name " + ab.name);

                UpdateText.text = UpdateText.text + "\n ab名称 " + ab.name;


                foreach (var name in ab.GetAllAssetNames())
                {
                    Debug.Log("asset name " + name);
                    UpdateText.text = UpdateText.text + "\n asset 名称 " + name;

                }
            }
            Addressables.Release(download);
        }
        Addressables.Release(downloadsize);
    }


    IEnumerator LoadScene(string senceName)
    {
        // 异步加载场景(如果场景资源没有下载,会自动下载),

        var handle = Addressables.LoadSceneAsync(senceName);
        if (handle.Status == AsyncOperationStatus.Failed)
        {
            Debug.LogError("场景加载异常: " + handle.OperationException.ToString());
            yield break;
        }
        while (!handle.IsDone)
        {
            // 进度(0~1)
            float percentage = handle.PercentComplete;
            Debug.Log("进度: " + percentage);
            yield return null;
        }

        Debug.Log("场景加载完毕");
    }


    IEnumerator DoUpdateAddressadble()
    {
        AsyncOperationHandle<IResourceLocator> initHandle = Addressables.InitializeAsync();
        yield return initHandle;

        // 检测更新
        var checkHandle = Addressables.CheckForCatalogUpdates(false);
        yield return checkHandle;
        if (checkHandle.Status != AsyncOperationStatus.Succeeded)
        {
            OnError("CheckForCatalogUpdates Error\n" + checkHandle.OperationException.ToString());
            yield break;
        }

        if (checkHandle.Result.Count > 0)
        {
            var updateHandle = Addressables.UpdateCatalogs(checkHandle.Result, false);
            yield return updateHandle;

            if (updateHandle.Status != AsyncOperationStatus.Succeeded)
            {
                OnError("UpdateCatalogs Error\n" + updateHandle.OperationException.ToString());
                yield break;
            }

            // 更新列表迭代器
            List<IResourceLocator> locators = updateHandle.Result;
            foreach (var locator in locators)
            {
                List<object> keys = new List<object>();
                keys.AddRange(locator.Keys);
                // 获取待下载的文件总大小
                var sizeHandle = Addressables.GetDownloadSizeAsync(keys);
                yield return sizeHandle;
                if (sizeHandle.Status != AsyncOperationStatus.Succeeded)
                {
                    OnError("GetDownloadSizeAsync Error\n" + sizeHandle.OperationException.ToString());
                    yield break;
                }

                long totalDownloadSize = sizeHandle.Result;
                UpdateText.text = UpdateText.text + "\ndownload size : " + totalDownloadSize;
                Debug.Log("download size : " + totalDownloadSize);
                if (totalDownloadSize > 0)
                {
                    // 下载
                    var downloadHandle = Addressables.DownloadDependenciesAsync(keys, Addressables.MergeMode.Union, false);
                    //yield return downloadHandle;
                    while (!downloadHandle.IsDone)
                    {
                        if (downloadHandle.Status == AsyncOperationStatus.Failed)
                        {
                            OnError("DownloadDependenciesAsync Error\n" + downloadHandle.OperationException.ToString());
                            yield break;
                        }
                        // 下载进度
                        float percentage = downloadHandle.PercentComplete;


                        Debug.Log($"已下载: {percentage}");
                        DownText.text = $"已下载: {Mathf.Round(percentage * 100)}%";
                        Slider.value = percentage;
                        if (percentage >= 0.9f)//如果进度条已经到达90%
                        {
                            Slider.value = 1; //那就让进度条的值编变成1
                        }

                        yield return null;
                    }
                    yield return downloadHandle;
                    if (downloadHandle.Status == AsyncOperationStatus.Succeeded)
                    {
                        Debug.Log("下载完毕!");
                        DownText.text = DownText.text + " 下载完毕";
                    }
                }
            }
        }
        else
        {
            UpdateText.text = UpdateText.text + "\n没有检测到更新";
        }

        // 进入游戏
        EnterPro();
    }
    // 进入游戏
    void EnterPro()
    {
        // TODO
        UpdateText.text = UpdateText.text + "\n进入游戏场景";
        Debug.Log("进入游戏");
    }
    private void OnError(string msg)
    {
        UpdateText.text = UpdateText.text + $"\n{msg}\n请重试! ";
    }



}

注意使用代码更新时,需要修改热AddressableAssetSettings更新设置否则代码将无法检测拦截更新信息
Unity 3D模型展示框架篇之资源打包、加载、热更(二)做完以上工作,进行热更Groups的设置与修改。创建一个远程更新组并命名为RemoteGroup,按照图中所示进行热更资源配置。
Unity 3D模型展示框架篇之资源打包、加载、热更(二)配置热更资源服务器,web服务器为IIS,如何创建应用程序这里不做赘述,有不懂的小伙伴留言。这里注意将热更新资源.bundle.hash加入到应用程序的MIME中使得Unity项目可以访问到,否则404无法访问资源。
Unity 3D模型展示框架篇之资源打包、加载、热更(二)
配置好IIS服务器后访问地址 http://www.btlfxx.cn/unity_cmj/tempas,没毛病!!!
Unity 3D模型展示框架篇之资源打包、加载、热更(二)

Unity项目中配置远程更新服务器
Unity 3D模型展示框架篇之资源打包、加载、热更(二)配置信息
Unity 3D模型展示框架篇之资源打包、加载、热更(二)配置完成后New Build 一下,重新生成一下.bin文件。
Unity 3D模型展示框架篇之资源打包、加载、热更(二)构建成功信息
Unity 3D模型展示框架篇之资源打包、加载、热更(二)

打开本地构建热更资源的文件夹,看到如下文件信息。这些就是需要Copy到服务器上的热更文件,Copy服务器之后在进行如下配置。
Unity 3D模型展示框架篇之资源打包、加载、热更(二)

确定项目热更新的工作模式
Unity 3D模型展示框架篇之资源打包、加载、热更(二)运行Unity项目
Unity 3D模型展示框架篇之资源打包、加载、热更(二)点击检测并更新
Unity 3D模型展示框架篇之资源打包、加载、热更(二)点击登录后跳转场景
Unity 3D模型展示框架篇之资源打包、加载、热更(二)下面做热更操作,将Switch预制体中的模块隐藏掉。重新构建资源热更包,将热更包Copy到服务器上。

Unity 3D模型展示框架篇之资源打包、加载、热更(二)
Unity 3D模型展示框架篇之资源打包、加载、热更(二)运行项目,下面做一个能下载资源的热更包。
Unity 3D模型展示框架篇之资源打包、加载、热更(二)
RemoteGroup组中的Switch中的主体添加一个3D物体,重新打包。可以发现3个更新文件,组remotegroup新生成一个资源包,只需要Copy这3个文件到服务器上。

Unity 3D模型展示框架篇之资源打包、加载、热更(二)演示效果

Unity AA热更新文章来源地址https://www.toymoban.com/news/detail-419104.html

到了这里,关于Unity 3D模型展示框架篇之资源打包、加载、热更(二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Unity 3D模型展示之webGL平台展现

    Unity 3D模型展示之webGL平台展现

    在之前的项目基础上我们已经打包后在PC端进行展示了。这篇文章主要介绍在切换到webGL上时效果展示不出来需要进行调整,特此记录一下。 1.平台切换 选择WebGL平台切换,没有的可以进行安装,安装之后关闭IDE重新启动。选择WebGL切换,参数参照以下设置即可。 2.构建WebGL项

    2024年02月01日
    浏览(7)
  • IOS使用Unity容器动态加载3D模型

    IOS使用Unity容器动态加载3D模型

    项目背景 我们的APP是一个数字藏品平台,里面的很多藏品需要展示3D模型,3D模型里面可能会包含场景,动画,交互。而对应3D场景来说,考虑到要同时支持iOS端,安卓端,Unity是个天然的优秀方案。 对于Unity容器来说,需要满足如下的功能: 1.在APP启动时,需要满足动态下载

    2024年03月18日
    浏览(12)
  • Blender模型资源如何正确导出FBX并导入Unity(一):3D模型

    Blender模型资源如何正确导出FBX并导入Unity(一):3D模型

      目录 前言 一、问题分析 二、正确搭配 总结 第一次使用Blender制作游戏资源并导出FBX到Unity时,往往会出现不正确的缩放,旋转等问题,本文对一些常用的导出选项做一些说明 软件版本:Blender3.4 Unity2021 我们先看一下如果使用Blender默认配置导出FBX到Unity会怎么样 问题包括

    2024年02月08日
    浏览(185)
  • GameFrameWork框架(Unity3D)使用笔记(八) 实现场景加载进度条

    GameFrameWork框架(Unity3D)使用笔记(八) 实现场景加载进度条

            游戏在转换场景的时候,需要花费时间来加载相关的资源。而这个过程往往因为游戏场景的规模和复杂度以及玩家电脑配置的原因花费一小段时间(虽然这个项目里用不到)。         所以,如果这一小段时间,画面就卡在这里,啥也做不了,玩家也不知道啥时候能

    2024年02月02日
    浏览(9)
  • 【Unity】实用功能开发(一)实现在UI中用RawImage实时展示3D模型(背景透明,并通过UI防止3D场景遮挡)并可以通过分层完成:游戏中的人物状态展示界面,小地图,人物实时头像状态等功能

    【Unity】实用功能开发(一)实现在UI中用RawImage实时展示3D模型(背景透明,并通过UI防止3D场景遮挡)并可以通过分层完成:游戏中的人物状态展示界面,小地图,人物实时头像状态等功能

    有时由于项目效果需要,部分功能的实现受到阻碍,这里收集一些已实现的思路和方法,每次会记录大致需求和遇到的问题,如果有更好的想法,欢迎评论区讨论!!! 目录 功能描述: 需求描述: 实现步骤: ①为需要展示的内容区分层级: ②在场景中添加一个摄像机,并

    2024年02月04日
    浏览(12)
  • vue项目打包,解决静态资源无法加载和路由加载无效(404)问题

    vue项目打包,解决静态资源无法加载和路由加载无效(404)问题

    打包后的项目静态资源无法使用,导致页面空白 静态资源无法使用,那就说明项目打包后,图片和其他静态资源文件相对路径不对,此时找到config里面的index.js,在build模块下加入 assetsPublicPath: \\\'./\\\',  如下图所示,或者是在打包完的dist文件夹中找里面的.js文件,将其中的\\\'/\\\'替

    2024年02月08日
    浏览(11)
  • Unity 场景加载和资源加载

    Unity 场景加载和资源加载

    一个游戏往往都是由很多场景组成的,例如会有主界面场景、战斗场景…等,不同的场景也是由若干的资源组合而成,在游戏的制作过程中,场景和资源的加载是不可或缺的。不管是场景还是资源都会涉及到加载的问题,在什么时候进行场景或资源的加载?场景的加载和资源

    2024年02月04日
    浏览(9)
  • Unity使用 Addressables 预加载所有资源,提现加载资源,发布webgl加载缓慢问题

    Unity使用 Addressables 预加载所有资源,提现加载资源,发布webgl加载缓慢问题

    Addressables 我也是刚接触,知道的不是很多,基本的用法还是知道一些的 1 .在Window–Package Manager里找到Addressables进行安装   2.选择资源,点击Assets中的一个资源,在Inspector面板上就会出现一个勾选Assressable,也就是是否加入资源打包的分组,和AssetBundle分组是一个性质。选上以

    2023年04月08日
    浏览(11)
  • Unity 3d角色展示脚本(旋转 平移 缩放)展示界面

    不考虑性能 很简陋的一个功能,主要是用于角色渲染的观察用,比simplecontroller要好用一点

    2024年02月11日
    浏览(9)
  • 【虚幻引擎UE】UE5 Pak资源分包加密打包与加载(安卓篇)

    【虚幻引擎UE】UE5 Pak资源分包加密打包与加载(安卓篇)

    【虚幻引擎UE】UE5 Pak分包加密及热更新(安卓篇) 相关文章: 1.介绍了安卓项目打包的基本操作: 【虚幻引擎UE】UE5仅需5个步骤快速实现AR项目调试与打包(安卓篇) https://tjgzs.blog.csdn.net/article/details/126097508 2.介绍了PAK加载的基本操作: 【虚幻引擎UE】UE5 热更新动态PAK资源加

    2024年02月08日
    浏览(8)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包