[游戏开发][Unity]Assetbundle加载篇(4)加载资源流程详解

文章详细介绍了Unity中的资源管理框架,包括ResourceManager如何维护Loader,如TextFileLoader,以及如何避免重复实例化。当多个地方同时加载同一资源时,如何共用Loader进行加载任务。同时提到了AssetLoaderBase的LoadAsync方法和加载状态管理。最后讨论了资源的卸载方法,如Resources.UnloadAsset和AssetBundle.Unload。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 目录

打包与资源加载框架目录

正文

ResourceManager维护所有Loader,除了GameObjectLoader外,其他类型的资源都是一个路径一个Loader,由于预设可以复制,所以每复制一个预设,就创建一个GameObjectLoader,后面会详细介绍

下面先来个简单的例子,后面介绍GameObjectLoader例子。

假设此处有A/B/C三个地方同时加载"Assets/Works/Res/CS_Bytes/UIConfig.bytes"文件

假设加载UIConfig.bytes文件需要10秒钟时间,纯假设哈,加载二进制文件一般一帧就完成了。

下面的代码代表是A的代码,BC大概差不多

  protected void Init<T>(string byteFileName) where T : TableBase
    {
        LoadAssetUtility.LoadTextAsset("CS_Bytes/UIConfig.bytes", LoadBytesCallback, true);
    }

    void LoadBytesCallback(AssetLoaderBase loader, bool state)
    {
        if (state == true)
        {
            TextFileLoader textLoader = (TextFileLoader)loader;
            if (textLoader == null)
            {
                LogManager.LogError("TableCtrl textLoader is null: " + loader._resPath);
                return;
            }
            Parser_Table(textLoader.GetBytes());
            LoadTableState loadTable = FSMManager.Instance.GetState<LoadTableState>();
            loadTable.LoadTableCallback();
        }
        else
            LogManager.LogError("TableCtrl load table fail,_resPath: " + loader._resPath);
    }

 LoadAssetUtility代码:


    //加载文本
    //加载bytes/xml等文本文件也用该接口
    public static TextFileLoader LoadTextAsset(string _url, OnLoadCallback callback, bool AutoRelease = false)
    {
        return ResourceManager.Instance.GetTextFileLoader(_url, callback, AutoRelease);
    }

 ResourceManager代码:

    public TextFileLoader GetTextFileLoader(string url, OnLoadCallback callback, bool AutoRelease)
    {
        TextFileLoader loader = null;
        if (_TextLoaderPool.ContainsKey(url))
            loader = _TextLoaderPool[url];
        else
        {
            loader = (TextFileLoader)_LoaderClassPool.GetAsset(typeof(TextFileLoader));
            _TextLoaderPool[url] = (TextFileLoader)loader;
        }
        loader.LoadAsync(url, callback, typeof(TextAsset), AutoRelease);
        return loader;
    }

看ResourceManager代码也很好理解,如果_TextLoaderPool存在这个路径,则返回这个Loader,不要再重复实例化一个对象了,如果路径不存在,则创建一个Loader。假设第一个是A先加载,那么肯定会创建一个TextFileLoader,等BC也加载时,返回的就是A启动的那个TextFileLoader。

 下面是AssetLoaderBase的代码,TextFileLoader继承AssetLoaderBase,上篇文章有讲,所有Loader都继承AssetLoaderBase

     public void LoadAsync(string path, OnLoadCallback callback, Type t, bool autoRelease = false)
    {
        if (callback == null)
        {
            LogManager.LogError("load callback cant be null,load task return");
            return;
        }
        //如果该Loader已有结果,则不重复开启加载任务
        if (_LoadState == AssetLoadState.LoadSuccess ||_LoadState == AssetLoadState.LoadFailed)
        {
            callback(this,_LoadState == AssetLoadState.LoadSuccess);
            return;
        }
        _prepareCallback += callback;
		_resPath = path;
        _LoadState = AssetLoadState.Loading;
        LoadTaskManager.Instance.CreateLoadTask(this, OnLoadTaskFinish,t);
	}

解读一下LoadAsync方法,callback是ABC传过来的加载结果回调方法,如果Loader已成功或失败,直接通知callback加载结果并return。我们的例子很显然没加载成功,代码会继续往下走。

_prepareCallback保存所有使用层回调,ABC的回调方法都会保存到这里

_resPath就是"CS_Bytes/UIConfig.bytes",请注意,我们所有资源都放在"Assets/Works/Res/"内,所以前缀路径写在LoadTask中,而不是发起加载的地方。

_LoadState = AssetLoadState.Loading;也比较好理解,设置加载状态

重点来了!!!!

LoadTaskManager.Instance.CreateLoadTask(this, OnLoadTaskFinish,t);里的OnLoadTaskFinish方法是TextFileLoader的,而不是基类的OnLoadTaskFinish方法。

基类里的OnLoadTaskFinish是抽象方法,压根没有实现,如下图

此时,ABC的加载回调已保存到这个TextFileLoader中,并开启了加载任务

提问:为何开启加载任务??

解答:请记住,Loader的作用是维护实例化后的资源,并不负责加载工作。

下一篇文章开启加载任务

Bundle卸载

资源卸载

19. 单纯卸载一个 AB 包解压的内存需要使用 Resources.UnloadAsset(Object assetToUnload);

- 20. 卸载全部的目前没有使用的解压的内存需要使用 Resources.UnloadUnusedAssets();

- 21. 单纯卸载一个 AB 包的解压的内存与压缩镜像内存 AssetBundle.Unload(true);

- 22. 卸载所有 AB 包目前没有在被使用的解压的内存与压缩镜像内存 AssetBundle.UnloadAllAssetBundles(false);

- 23. 卸载所有 AB 包的解压的内存与压缩镜像内存 AssetBundle.UnloadAllAssetBundles(true);
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Little丶Seven

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值