Search Unity

Still not clear on the recommended path for streaming prefabs in and out of ram without hiccups

Discussion in 'Asset Bundles' started by hippocoder, Apr 23, 2017.

  1. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Hiya,

    Still not sure on the correct way to use asset bundles or if they should be used to stream prefabs in and when done with it, clear them out of ram.

    There appears to be a lot of approaches but I'm interested in the Unity-recommended way, which doesn't seem very clearly documented.

    I'd like to be able to load in a prefab on demand, which can consist of absolutely anything from unique textures to models, to animations or just be a plain old mesh, and do that without affecting framerate perceptibly, use said prefab then remove it from memory in a way that also does not cause hiccups.

    Load prefab asynchronously, use it, and remove it when done, all without hiccups.

    What's the "right" way now asset bundles are being improved?
     
  2. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    A few non-obvious things for you to consider:

    - LoadAssetAsync is not really async. At some point it was, but then when Unity shipped webGL, it had an issue with Async loading from asset bundles and they disabled it. So loading of asset bundles blocks the main thread.
    - Prefabs/Scenes are bloated/large formats unsuitable for streaming. For our streaming world, we pack things into our own format. A 180x180 meter area of the world in our format takes about 30k, as a prefab it's about 1.2 megs, and as a scene it's almost 4 megs. So, IMO, I would suggest creating your own format for scene placement data if you have a lot of that.
    - Loading data via asset bundle will always create garbage which will eventually have to be collected which will cause a hitch. WebRequest can help with this, apparently, but every time we try to use it we have to go back to WWW due to various bugs. (WWW loads the bundle into managed memory, so bloats the mono-heap)
    - Various things like lightmap data, etc, don't stream well.

    in general, Unity is not designed for streaming worlds. It's massively single threaded, uses an ancient garbage collection model that creates massive hitches, and asset bundles are a general system for loading data into a game from an external source (and not a great one at that, IMO) - not a level streaming system. Depending on your needs, it's certainly possible to get something workable (we did), but it's not an easy fit, and will take a ton of development effort.
     
  3. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Right, that is the single most helpful reply I've had on the subject, thank you very much indeed! A lot to ponder.

    The take away is that Unity simply isn't any good at it and custom is needed.
     
  4. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    332
    - LoadAssetAsync is not really async. - This is fixed starting with 2017.1.0a3 and on.

    - WWW loads the bundle into managed memory. - This should only be true if you are loading an Lzma bundle from disk. Lz4 and Uncompressed bundles should only load what you ask for off disk into memory + small read buffers needed by the VFS. One thing to note is that if you use WWW.LoadFromCacheOrDownload or the newer UnityWebRequest.GetAssetBundle, this will download a Lzma bundle, and recompress it on the fly while saving it into the cache to Lz4 or Uncompressed depending on Caching.compressionEnabled flag (true = Lz4, false = Uncompressed).
     
    tonialatalo likes this.
  5. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Any chance this is going to be ported back to the 5.3 line? Too risky for us to upgrade major versions, and it causes major loading hitches for us, even though we keep our total loads really small.
     
  6. AFrisby

    AFrisby

    Joined:
    Apr 14, 2010
    Posts:
    223
    Ditto, albeit 5.6.
     
  7. Reichert

    Reichert

    Unity Technologies

    Joined:
    Jun 20, 2014
    Posts:
    63
    To clarify this a little bit, async loading was only fixed for loose asset bundles in 2017.1, not scene bundles. We are fixing streaming from scene bundles in the upcoming build pipeline refactor. Unlikely that fixes for streaming will be backported as they are risky by standards of our sustained engineering process.
     
    tonialatalo likes this.
  8. Skolstvo

    Skolstvo

    Joined:
    Dec 21, 2015
    Posts:
    107
    I'm not quite sure why async loading was broken because of WebGL. I mean, WebGL is still not multi-threaded. What's going on? How did you "fix it"?
     
    tonialatalo likes this.