14.资源加载-Resource

本文介绍了GameFramework中资源加载Resource的实现,主要关注AssetBundle在热更新场景下的应用。内容包括资源概念、加载流程、类图以及如何使用。Unity新版本提供了Addressable实现类似功能,但此处仍围绕AssetBundle进行热更资源的添加、打包、下载和使用,遵循标准的热更新流程。
摘要由CSDN通过智能技术生成

GameFramework资源加载Resource

介绍

这里只是加载热更新的资源,unity 新版本已经提供 Addressable 实现了该功能
所以这里是围绕 AssetBundle 实现了热更资源的添加,打包,下载,使用
跟通常的热更流程并无不同:
- 添加要热更的资源
- 打包 AssetBundle 上传
- 应用按平台下载 AssetBundle
- 加载 AssetBundle 并从中取得所需资源

资源概念

  • Asset 1个资源,跟 Unity 的 Asset 对应
  • Resource 可以理解为文件,对应 AssetBundle ,包含多个 Asset
  • FileSystem 文件系统,可以把多个 AssetBundle 打包成1个文件
  • ResourceGroup 资源组,把多个 Resource 分成1组,主要是为了热更新时能分组更新

资源加载流程

  • 找到 Asset 所属 Resource
  • 找到 Resource 所属 FileSystem,如果有的话
  • 使用 LoadResourceAgentHelperBase 加载 FileSystem 并提取出 Resource
  • 从 Resource 中加载 Asset

类图

IResourceManager
ResourceManager
资源管理器
负责从远程下载 AssetBundle
并从从 AssetBundle 中加载资源
EditorResourceComponent
利用 AssetDatabase 加载资源
IFileSystem
ResourceLoader
负责加载资源

使用

    //  比如 DataProvider 中读取数据表部分
    DataProvider.ReadData(string dataAssetName, int priority, object userData)
    {
        //  热更资源打包时就会记录下该资源所属AssetBundle,以及是否多个AssetBundle打包成一个文件等信息
        //  所以这里可以用 HasAsset 获得信息,然后再加载
        IResourceManager m_ResourceManager;
        HasAssetResult result = m_ResourceManager.HasAsset(dataAssetName);

        //  不同类型资源要用不同方法加载, 这个类型是你添加打包资源时设置的
        //  带 FileSystem 和不带 FileSystem 的用同一个函数加载,因为配置信息中已经包含了这个信息,内部会自动处理
        //  Asset 就是正常的从 AssetBundle 中加载 Asset,会检测依赖关系并先加载依赖项
        //  Binary 就是常说的 raw 资源,比如 视频 音频 图片等,不会打包成 AssetBundle,1个resource只能包含1个asset
        //      内部其实是用 asset 找到 resource ,然后加载 resource 对应的文件当成 asset 返回
        switch (result)
        {
            case HasAssetResult.AssetOnDisk:
            case HasAssetResult.AssetOnFileSystem:
                m_ResourceManager.LoadAsset(dataAssetName, priority, m_LoadAssetCallbacks, userData);
                break;

            case HasAssetResult.BinaryOnDisk:
                m_ResourceManager.LoadBinary(dataAssetName, m_LoadBinaryCallbacks, userData);
                break;

            case HasAssetResult.BinaryOnFileSystem:
                int dataLength = m_ResourceManager.GetBinaryLength(dataAssetName);
                m_ResourceManager.LoadBinaryFromFileSystem(dataAssetName, s_CachedBytes);
                m_DataProviderHelper.ReadData(m_Owner, dataAssetName, s_CachedBytes, 0, dataLength, userData);
                break;
        }
    }

资源加载代码

    //  判断 Asset  所属 Resource ,以及依赖的 Resource,对标 Asset 所属 AssetBundle ,以及依赖的 AssetBundle
    ResourceManager.LoadAsset(string assetName, LoadAssetCallbacks loadAssetCallbacks)
    {
        ResourceLoader.LoadAsset(string assetName, Type assetType, int priority, LoadAssetCallbacks loadAssetCallbacks, object userData)
        {
            ResourceInfo resourceInfo = null;
            string[] dependencyAssetNames = null;
            //  获得 Asset 所属的 Resource 和 依赖的 AssetList
            CheckAsset(assetName, out resourceInfo, out dependencyAssetNames);

            //  建立加载任务
            LoadAssetTask mainTask = LoadAssetTask.Create(assetName, assetType, priority, resourceInfo, dependencyAssetNames, loadAssetCallbacks, userData);
            m_TaskPool.AddTask(mainTask)
            {
                TaskTool.Update()
                {
                    TaskTool.ProcessWaitingTasks()
                    {
                        ITaskAgent<T> agent = m_FreeAgents.Pop();
                        StartTaskStatus status = agent.Start(task)  //  LoadResourceAgent.Start(LoadAssetTask task)
                        {
                            //DefaultLoadResourceAgentHelper
                            ResourceInfo resourceInfo = m_Task.ResourceInfo;
                            string fullPath = Utility.Path.GetRegularPath(Path.Combine(resourceInfo.StorageInReadOnly ? m_ReadOnlyPath : m_ReadWritePath, resourceInfo.UseFileSystem ? resourceInfo.FileSystemName : resourceInfo.ResourceName.FullName));
                            if (resourceInfo.LoadType == LoadType.LoadFromFile)
                            {
                                if (resourceInfo.UseFileSystem)
                                {
                                    IFileSystem fileSystem = m_ResourceLoader.m_ResourceManager.GetFileSystem(resourceInfo.FileSystemName, resourceInfo.StorageInReadOnly);
                                    m_Helper.ReadFile(fileSystem, resourceInfo.ResourceName.FullName)   //  DefaultLoadResourceAgentHelper.ReadFile(fullPath)
                                    {
                                        -------------------------------> 接下面
                                    }
                                }
                                else
                                {
                                    m_Helper.ReadFile(fullPath) //  DefaultLoadResourceAgentHelper.ReadFile(fullPath)
                                    {
                                        -------------------------------> 接下面
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    //  加载 Resource ,对标 AssetBundle
    DefaultLoadResourceAgentHelper.ReadFile(fullPath)
    {
        //  加载 AssetBundle
        m_FileAssetBundleCreateRequest = AssetBundle.LoadFromFileAsync(fullPath)
        {
            DefaultLoadResourceAgentHelper.Update()
            {
                DefaultLoadResourceAgentHelper.UpdateFileAssetBundleCreateRequest()
                {
                    if (m_FileAssetBundleCreateRequest.isDone)
                    {
                        //  AssetBundle 加载完成,发出通知
                        m_LoadResourceAgentHelperReadFileCompleteEventHandler(this, loadResourceAgentHelperLoadCompleteEventArgs)
                        {
                            LoadResourceAgent.OnLoadResourceAgentHelperReadFileComplete()
                            {
                                //  e.Resource 就是 AssetBundle
                                ResourceObject resourceObject = ResourceObject.Create(m_Task.ResourceInfo.ResourceName.Name, e.Resource, m_ResourceHelper, m_ResourceLoader);
                                m_ResourceLoader.m_ResourcePool.Register(resourceObject, true);
                                OnResourceObjectReady(resourceObject)
                                {
                                    //  从 AssetBundle 中加载 Asset
                                    m_Task.LoadMain(this, resourceObject)   //  LoadResourceTaskBase.LoadMain(LoadResourceAgent agent, ResourceObject resourceObject)
                                    {
                                        -------------------------------> 接下面
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    //  从 Resource 中加载 Asset ,对标从 AssetBundle 中加载 Asset
    LoadResourceTaskBase.LoadMain(LoadResourceAgent agent, ResourceObject resourceObject)
    {
        m_ResourceObject = resourceObject;
        //  resourceObject.Target 就是 AssetBundle,这里用 AssetBundle 加载 Asset
        agent.Helper.LoadAsset(resourceObject.Target, AssetName, AssetType, IsScene)    //  DefaultLoadResourceAgentHelper.LoadAsset(object resource, string assetName, Type assetType, bool isScene)
        {
            m_AssetBundleRequest = assetBundle.LoadAssetAsync(assetName)
            {
                DefaultLoadResourceAgentHelper.UpdateAssetBundleRequest()
                {
                    if (m_AssetBundleRequest.isDone)
                    {
                        m_LoadResourceAgentHelperLoadCompleteEventHandler(this, loadResourceAgentHelperLoadCompleteEventArgs)
                        {
                            LoadResourceAgent.OnLoadResourceAgentHelperLoadComplete(object sender, LoadResourceAgentHelperLoadCompleteEventArgs e)
                            {
                                //  到这里 Asset 加载成功
                                //  e.Asset 就是 Asset, AssetObject 代表 Asset
                                AssetObject assetObject = AssetObject.Create(m_Task.AssetName, e.Asset, dependencyAssets, m_Task.ResourceObject.Target, m_ResourceHelper, m_ResourceLoader);
                                m_ResourceLoader.m_AssetPool.Register(assetObject, true);

                                //  通知加载完成
                                OnAssetObjectReady(assetObject)
                                {
                                    m_Task.OnLoadAssetSuccess(this, asset, (float)(DateTime.UtcNow - m_Task.StartTime).TotalSeconds)    //  LoadAssetTask.OnLoadAssetSuccess()
                                    {
                                        //  资源加载完成,发出完成通知
                                        m_LoadAssetCallbacks.LoadAssetSuccessCallback(AssetName, asset, duration, UserData);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值