Search Unity

Feedback Loading Resource creates massive lagspikes

Discussion in 'Editor & General Support' started by joshcamas, Aug 30, 2019.

  1. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    787
    Hello!

    For some reason, when I load a prefab and instantiate as a Resource using Resources.LoadAsync, this results in massive lagspikes in the build. (IE 1,000 - 300 ms). I've made sure to set Application.backgroundLoadingPriority to low.



    If I instantiate using a normal reference, or even load it then instantiate using Addressables, this lagspike doesn't occur. This is extremely odd.

    Is this a known limitation with Resources?

    Josh

    EDIT: I tested it without instantiation: in other words, ONLY using Resources.LoadAsync. And the lag still occurs. The prefab I'm trying to load does pack a lot of data, sort of... but loading from Addressables doesn't cause lag, and one would imagine that loading an asset using Resources asynchronously would simply make the operation take a long time, even if the prefab was sizable. So I'm not sure what's going on here.
     
    Last edited: Aug 30, 2019
  2. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    787
  3. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    6,281
    I don't know the answer, but my understanding is when you load using Resources it loads the asset into memory at that time. When you use a normal reference the resource is loaded when the scene initially loads (so the lag is during the scene transition instead of while in the middle of a scene) so when you instantiate from a normal reference there is no loading occurring, so no associated lag spike other than that caused just by the instantiation of the object. I haven't tried addressables.

    edit:
    Also, async operations in the editor aren't actually async - instead they block (at least that is the case with async scene loading, and I'd assume that is the case most everywhere). So make sure you're testing this in a build.
     
    Last edited: Sep 10, 2019
  4. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    787
    The issue isn't with instantiation, since the lag still occurs when all I do is load the resource into memory. (note this is not a scene, but a prefab) Since it's supposed to be async, causing the game to freeze for 1,000 ms isn't a good outcome oof
     
  5. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    6,281
    Sorry, just edited my above post. Make sure you are testing this in a build, not the editor, as async operations block the main thread while running the in the editor (and I believe webGL also).
     
  6. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    787
    Yus this is in build ☺️☺️ thank ya
     
  7. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    There are two approach I know of to address this.

    For resources that you use in most of your scenes, adding the prefab to "Preloaded Assets" in the Player settings will cause those to be loaded into memory right at the start of the game. This will significantly reduce the performance hit of instantiating more of that prefab.

    upload_2019-9-10_16-7-49.png

    I generally only use this approach for objects that are in pretty much every scene in the game.


    The other approach is more generally used for dynamic assets you only need in a subset of scenes. I use the Addressables system in my game, but it should be pretty much the same for objects in Resources of if you're using Asset Bundles. Anyway, each of my scenes has a SceneController script on it that contains a list of prefabs that should be pre-loaded. When the scene is initially loaded, while my "Loading" screen is still showing, I Load each of those assets in advance so that when I later instantiate them the performance impact is minimal. Basically, I just call "Addressables.LoadAssetAsync<GameObject>(address)" for each of the things I need to preload.

    This approach require a bit of curation to ensure that ensure that each scene preloads the correct assets it's going to use. That's a little bit of work, but it's pretty simple.
     
    joshcamas likes this.
  8. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    787
    Sadly my world is an open world game, so loading my entire map into memory is simply not a solution for me

    Thank you for explaining what works for you though!! :)
     
  9. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    Ah. Well, I've never used this asset before, so I don't "recommend" it, but I believe that I've seen a lot of people mention using it for large, open-world games:

    https://assetstore.unity.com/packages/tools/utilities/world-streamer-36486

    You'd definitely want to verify that it actually does what you want, and prevents the game from hanging when loading up the next chunk of stuff.
     
  10. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    787
    Thanks for the link, I've already built my own world streamer and heavily into my current project, so sadly using another workflow isn't a solution for me. I know that world streamer uses scenes to split up their world, so that explains how they manage to reduce memory hiccups.

    My main reason for making this post is to understand why Resource.LoadAsync has massive spike issues, but Addressable loading async does not.