Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Alternative to Resources folder

Discussion in 'Editor & General Support' started by Mahdi-Jeddi, Jul 3, 2016.

  1. Mahdi-Jeddi

    Mahdi-Jeddi

    Joined:
    Dec 21, 2012
    Posts:
    27
    We're making a strategy/simulation game in which we have unique image for each mission. Until now I saved these images in the resources folder and loaded them by Resoruces.Load() whenever needed.

    Problem is, we have thousands of these missions and all these files in the Resources folder makes the game freeze a few seconds (on some systems up to 10 seconds) before loading the first scene:
    https://unity3d.com/learn/tutorials/topics/best-practices/resources-folder

    What are my options here? I tried adding a link to each image in my db (which is a ScriptableObject), but it just loads all of the images at startup! I even tried creating other ScriptableObjects as prefabs which contain the link to each image, but it still loads all the images. I heard that AssetBundles are the way to go, but I'm not sure if creating thousands of AssetBundles is even possible (or wise?) in Unity. Is there any other way? Some kind of a weak reference to the textures so that they won't load until I instantiate them?
     
  2. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,532
    I am not sure why the textures are being loaded when you link them in your DB (unless you have a single DB that points to all textures...)

    A couple of suggestions:

    1. Are you only loading images? move all images out of Resources into another folder (e.g: Textures). Create a scriptable object type that points to the images you need. The images will not be loaded on startup, and they will not exist in Resources (e.g: it won't stall your game before the first scene is loaded). Note that you will need 1 scriptable object per mission... each will point to the texture it needs.

    2. Build asset bundles that will contain your textures. Basically it's kinda similar to the first suggestion but the images will be contained in an asset bundle. Seems like a bit of an overkill if all you need per mission is a texture.
     
  3. darkhog

    darkhog

    Joined:
    Dec 4, 2012
    Posts:
    2,219
    You also could put these images into streamingassets and load them from PNGs directly. It's actually very fast from what I've tested. Not to mention that you also get smaller build size since Unity's compression is less efficient than PNG (with max, 9 level of compression), not to mention JPG (even when quality is set to 100%).
     
  4. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,532
    Martin_H likes this.
  5. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,569
    Creating thousands of AssetBundles should be fine. If you're only packing a single image into each bundle then you'll be producing quite a lot of overhead, but if you don't care about size on disk then it shouldn't matter. If you want to reduce the overhead, you could try packing groups of images into the bundles.
     
  6. darkhog

    darkhog

    Joined:
    Dec 4, 2012
    Posts:
    2,219
    For stuff like mission images it should be just fine though, since ideally you'd only load one at a time (and replace already loaded one with newly loaded one as needed).
     
  7. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Why would you need thousands of asset bundles? One bundle can take thousands of assets.

    There is probably an optimum in the middle somewhere. For development speed, I would suggest throwing a couple hundred related images in each bundle.
     
  8. Mahdi-Jeddi

    Mahdi-Jeddi

    Joined:
    Dec 21, 2012
    Posts:
    27
    The problem is that I have to save the link to that scriptable object somewhere (in my DB?). and then when I load the object that holds the links, it immediately loads all of the images that are in all those scriptable objects. So, the actual problem is retaining the links to the assets.
     
  9. Mahdi-Jeddi

    Mahdi-Jeddi

    Joined:
    Dec 21, 2012
    Posts:
    27
    Thanks for the reply. I'll try the AssetBundle route when I have more time. I hope the build time for all the thousands of asset bundles is not that much :p
     
  10. Mahdi-Jeddi

    Mahdi-Jeddi

    Joined:
    Dec 21, 2012
    Posts:
    27
    If I make one asset bundle, then the moment I load the AssetBundle it will load all of the images, or can I load single assets from an AssetBundle? That would be fix everything!
     
  11. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,569
    It shouldn't be, but more importantly, once you've built the bundles once you won't need to build them again (unless you change the textures, upgrade to a version of Unity that changes the serialized data format, etc). By comparison, the Resources folder is being rebuilt every single time you do a build of your game.
     
  12. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,569
    If you make the AssetBundle with the 'Uncompressed' flag, then loading it from a file only reads the header information. You can then load single assets from it when you need them after that.
     
    Kiwasi likes this.
  13. Mahdi-Jeddi

    Mahdi-Jeddi

    Joined:
    Dec 21, 2012
    Posts:
    27
    That for me is a last resort solution as it will leave all of the assets in plain sight which is not a very good idea.
     
  14. Mahdi-Jeddi

    Mahdi-Jeddi

    Joined:
    Dec 21, 2012
    Posts:
    27
    Yay! I didn't thought of that. How do I load the asset bundles? They are saved in the streaming assets folder, right?
     
  15. Mahdi-Jeddi

    Mahdi-Jeddi

    Joined:
    Dec 21, 2012
    Posts:
    27
    Wow! That's exactly what I needed! Thanks a lot!
     
  16. darkhog

    darkhog

    Joined:
    Dec 4, 2012
    Posts:
    2,219
    Making game moddable is always a good idea. It increases life of the game. Just look at games where there are mod tools provided (say, any Valve game) vs. games that have none (say, Bastion). Your game may be good. It may be even great, as it is the case with Bastion. It may be even replayable, but eventually people WILL get bored of the same levels, even with things like New Game+. Adding modding support is the best way to ensure people will still play your game long after it is released, decades even (original Doom comes to mind...). People may buy your game just for the mods, even! Like it is the case with Skyrim.

    Whereas games with no mod support may be played once, twice and then people say Eh, whatever, time to uninstall this.
     
  17. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    8,697
    Mobile. Speed and memory are critical when managing limited resources.

    ^ This.
    It's all about planning. We have ~7k assetbundles. Several hundreds are single textures, many have multiple assets. Stuff like assets only used in the FUE, are bundled together, by faction. Promo, holiday, and/or story specific textures are individually bundled. The player may only see them once, or once a year. Stuff like that.
     
    Kiwasi likes this.