Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Force-loading assets that are rarely used (like muzzleflashes).

Discussion in 'Editor & General Support' started by cubrman, Apr 9, 2019.

  1. cubrman

    cubrman

    Joined:
    Jun 18, 2016
    Posts:
    409
    I noticed that if I launch my game, wait for it to load and then start shooting - the game lags severely for roughly 5-9 seconds before it starts working normal again. I believe this is due to some assets not being loaded as they are rarely used (muzzleflashes, particles, sounds). I plan on adding code that would create an artificial situation where a bot would fire bullets into different materials on camera so that everything can be loaded before I give controll to the player. But before I implement that I wanted to ask if there is another way of doing it, as I might be reinventing the wheel here.
     
  2. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,193
    Well, you have some options.

    The simplest thing is to add the prefab to Preloaded Assets under Project Settings -> Player:

    upload_2019-4-9_10-31-53.png

    That should make it very quick to instantiate the object at runtime, even if it's the first one you're instantiating. However, I believe it means those objects probably stick around in memory for the whole game. So, if the objects use a lot of memory, and/or are only used in a couple of scenes, they probably don't belong here.

    I use this for objects that are essentially everywhere in my game. But for other objects that aren't used as often, I have some logic in my scene controller base class that preloads certain objects depending on what the scene needs. It's slightly manual, as each scene needs to override a property to declare what kinds of dynamic objects it wants to preload to avoid instantiation hiccups. For example:

    Code (CSharp):
    1. protected override List<string> AddressablesToPreload => new List<string>() { AddressableConstants.Addressables.MilitaryWingAccessories.MilitaryWingDebris1x1x1Prefab };
    2.  
    This ultimately gets used by the base class to call `Addressables.LoadAsset<GameObject>()`. (Note that I'm using the Addressables package in the Package manager for asset management.)

    Anyway, your specific approach of actually having something fire shots at different surfaces seems unnecessarily complex to me. Better to just create a prefab that includes any other prefabs you might want to load, and instantiate that prefab while your scene is first loading.
     
  3. cubrman

    cubrman

    Joined:
    Jun 18, 2016
    Posts:
    409
    Wow that actually worked, thanks a lot!
     
  4. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    I believe another technique some developers use is when the scene loads to instantiate the prefab in a far off area of the scene and destroy it. You'd probably use this for prefabs only used in small portions of your game, that you don't want in Preloaded Assets.

    Object pooling is another technique that avoids this issue, as you instantiate ahead of time a number of the prefab and deactivate them. This will generally have better performance than even using Preloaded Assets, as activating and positioning a GameObject is faster than instantiating a prefab.
     
  5. cubrman

    cubrman

    Joined:
    Jun 18, 2016
    Posts:
    409
    Thanks, will keep in mind!