zoukankan      html  css  js  c++  java
  • AssetBundle异步加载被中断的问题

    在使用异步接口 yield return AssetBundle.ASyncLoad的时候,难免会想到:这个异步处理完之前如何Cancel掉这个任务?
    也就是一个AssetBundle加载到一半,现在要放弃加载,应该怎么处理?

    评论 分享
    10条回复

    无法CANCEL

    评论 分享

    Unity的接口里没有中断操作,但是可以在自己项目的ABMgr模块给业务逻辑层提供一个可中断的接口。也就是Mgr里加载好资源后,如果业务层不需要了,则不返回/不执行回调。至于这个“不需要”的资源是要缓存,还是卸载就得根据自己项目来了。

    评论 分享

    分享一个小的Unity文档上的坑吧,其实我也不知道答案,可能希望有源码的朋友帮忙看看。
    在异步请求一个AssetBundle的时候,会返回一个AssetBundleCreateRequest对象,Unity的官方文档上写AssetBundleCreateRequest.assetBundle的时候这样说:

    Description
    Asset object being loaded (Read Only).

    Note that accessing asset before isDone is true will stall the loading process.

    用了Stall这样一个词,我们之前理解Stall是停止的意思,以为这个接口的调用可以将异步请求打断,所以借助这个特性应用在“同一个AssetBundle正在被异步加载的过程中来了一个同步请求”这样的情况下。
    今天看到这个问题,又读了读这个文档,感觉Stall这个词并不是停止的意思,而更可能是“拖延”的意思。如果是一个异步加载请求,那么是在另外的线程里执行的,这时候如果有主线程的访问请求的话,应该会有跨线程的加锁逻辑,从而可能导致加载变得更慢。如果是停止的话,我觉得文档应该使用Stop这样更加明确的单词……

    当然这个是我个人的猜测,并不一定真的是这样。。。如果有其他朋友知道准确的意思也烦请告知~

    评论 2 分享
    • K
      kent

      会有一个资源锁,体现在Loading.LickPersistentManager,这时要控制依赖关系及同一时刻提取asset的数量。

    •  
      贾伟昊回复kent

      感谢回复~

     
    S

    碰到的问题和我一样呢, 最后我们是使用promise方式封装了资源加载的接口。
    返回的handle对象状态一旦凝固就不会再改变.

    ////code1
    op = loadasset()
    yield return op
    if op.error != nil then
      log("fail=" + op.error)
    end
    
    ////code2
    op:reject("next scene is loading")
    
    评论 分享

    image.png

    看到贾伟昊说到的这个问题,很激动地去看了一下API和UnityReferenceSource。由于项目一直在用5.6版本,2017和2018的AB这块还没测试过。5.6是肯定不能取消或者block获取到AB资源的,看新的Doc里面都提到了能block获取到资源,referenceSource中AB的API也提到了,asset的API中没有提到。理解应该是在异步没有完成之前,访问资源可以变成同步马上获取到该资源,有测试过的同学可以回答一下。如果真是这样,那就太好了,相信很多项目的设计上都是同步与异步并存的,只是绕过了同步加载一个正在异步加载资源的问题。Unity如果这块修改了,就可以完美解决同步加载一个正在异步加载资源的问题了。

    鉴于Unity Doc被坑过几次,更相信ReferenceSource里的,猜测AB也许实现了同步访问正在异步加载的资源,asset没有实现。

    评论 2 分享
    •  
      灰灰

      2017也是,异步没完成前直接访问asset会同步完成加载

    • L
      leeman回复灰灰

      有具体例子可以看一下怎么实现吗?现在也再纠结这个东西

     
    C

    我们之前的项目,无论是同步加载还是异步加载,都是以异步的方式写代码,就是为了解决这种不确定性

    评论 分享

    没法取消异步加载操作,但是通过在isDone之前直接访问Asset可以同步加载完成资源,也算中止异步加载操作吧。

    评论 分享
    C

    先异步加载1.ab,异步未完成时,直接同步加载该1.ab。
    此时会有类似的error:The asset bundle ‘’ can’t be loaded because another asset bundle with the same files are already loaded。直接忽略该错误即可。

    评论 2 分享
    • 直接忽略?难道是已经加载成功了?报错不准?

    • 官方说是保护性的提示,无任何副作用。

     
    L

    同一帧相同资源先调异步再调同步办法
    上面说的比较原理。我来直接上代码吧。造福大家
    abrequest = AssetBundle.LoadFromFileAsync(path)
    abrequest .assetBundle.Unload(false)
    ab = AssetBundle.LoadFromFile(path)
    这样会直接同步回来ab,但是会破坏原来异步的回调值 里面abreast.assetbundle 会变空不太好。
    还有一种办法是最后一句改为
    asset a =abrequest.assetBundle.asset
    这样原来异步的回调可以正常执行,同步也可以直接返回值。是一个比较好的解决方案。原来代码的逻辑改动小。

    评论 2 分享
    • 赞一个,方案可行

    • X
      xp

      没看懂

     
    Z

    在Unity2018.1.1f上测试了,可以通过获取bundle的操作来打断异步操作,使其改为同步加载。具体示例代码:

            AssetBundleCreateRequest abRequest = AssetBundle.LoadFromFileAsync(path);
    	abRequest.assetBundle.Unload(true);
            AssetBundle ab = abRequest.assetBundle;
            if (ab == null)
            {
                ab = AssetBundle.LoadFromFile(path);
                var assets = ab.LoadAllAssets();
                foreach (var item in assets)
                {
                    Debug.Log(item.name);
                }
            }
            else
            {
                var assets = ab.LoadAllAssets();
                foreach(var item in assets)
                {
                    Debug.Log(item.name);
                }
            }
    

    如果执行Unload(true), 那么这一行代码的本质是将异步改为同步,然后加载该bundle,再释放该bundle,下面会执行LoadFromFile操作。如果注释掉该执行代码,则直接获取assetbundle的操作返回的是同步加载的bundle,会执行else语句块中的代码。
    大家可以测试一下,我测试没有问题

  • 相关阅读:
    《那些年啊,那些事——一个程序员的奋斗史》——86
    《那些年啊,那些事——一个程序员的奋斗史》——84
    《那些年啊,那些事——一个程序员的奋斗史》——86
    《那些年啊,那些事——一个程序员的奋斗史》——85
    《那些年啊,那些事——一个程序员的奋斗史》——87
    《那些年啊,那些事——一个程序员的奋斗史》——85
    高RTSP兼容RTSP播放器网页无插件流媒体播放器EasyPlayerRTSPWin64位代码编译升级调试过程介绍
    海康大华摄像头高起播低延时RTSP网页无插件流媒体播放器EasyPlayerRTSPWin录像和抓图实现线程优化方案分享
    EasyRTMP获取H.264实时流并转化成为RTMP直播推流之EasyRTMPiOS屏幕推流如何获取视频帧
    海康大华网络摄像头高起播低延时RTSP网页无插件流媒体专用播放器EasyPlayerRTSP之GDI和D3D两种视频渲染方式的区别介绍
  • 原文地址:https://www.cnblogs.com/yptianma/p/11781124.html
Copyright © 2011-2022 走看看