Search Unity

AssetBundles, Resources.Load, and "Best Practice" in Unity 2017

Discussion in 'Editor & General Support' started by CarterG81, Sep 11, 2017.

  1. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    I was referred to the Unity documentation, which states that the Best Practice for Resources.Load is to not use it.
    Instead, to use AssetBundles.

    I went through the documentation several times, on multiple pages (tuts, best practice, api, etc.), and it was quite confusing, but not after I was convinced by Unity that AssetBundles are definitely the way to go. Nowhere can I get a clear or complete answer as to how & when assetbundles and their assets are loaded into memory. Not their manifest files. Not one specific asset. The entire bundle.

    I downloaded Unity's AssetBundleManager & sample scenes, and outside the editor they throw an error about not being able to download from my localhost IP. Same problem as seen here but as far as I can tell, there is no resolution.

    This sucks. Especially since I am not using AssetBundles to download anything via WWW. No internet required. I was just converting my project by supplanting Resources.Load with AssetBundles, as was told to me by the Unity documentation. I eventually came to realize, looking through AssetBundleManager's code, that it is specifically made for all the things I don't need (downloading asset bundles from an external server).

    So hours later I decided to stop with AssetBundleManager & removed it from my project. Ugh. I then read to put my AssetBundles in "StreamingAssets" folder inside of Unity, because that is how I am using them: included with the initial full game download. Creating my own assetbundle manager, I begin to test loading the bundles.

    Code (csharp):
    1. AssetBundle bundle2 = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/AssetBundles/Windows/" + "global_player");
    I notice the profiler isn't displaying anything loaded into memory. So when is the AssetBundle actually loaded into memory? Is this just loading the manifests?

    Did I just waste several days of my life working hard to read through the documentation, (fail to) understand AssetBundles, and then realize Unity's suggestion to "Not use Resources.Load" is wrong? Should I just be using Resources.Load? This is so incredibly frustrating. Even the documentation seems inconsistent from page to page, and most of it requires the AssetBundleManager which doesn't work for me outside the editor.

    For the love of god, I just wanted to load my Prefabs into memory so my game's framerate doesn't hitch when I instantiate. Resources.LoadAll() makes this so easy. Why the hell are AssetBundles so incredibly complex even when they're all going to be local files? And how is this best practice? It may be nice updating after the fact, but getting it setup is a PITA, and others have told me they don't even use it for that - they make their own custom patcher. So in what world is this "best" when Resources.Load() seems to work fine & when you need something more you make a custom solution?

    I wouldn't have spent so much precious dev work days if I knew this wasn't going to be as easy as it sounds.

    1. Create the AssetBundle
    2. Load the AssetBundle only when I want
    3. Instantiate from the AssetBundle
    Nothing about this is simple. And I've read multiple doc pages, repeatedly.
     
    Last edited: Sep 11, 2017
  2. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    It honestly seems like the best way to do anything when it comes to Unity is skim through their documentation, and then just browse the API or use intellisense to see what methods you can call & figure it out from there.

    I stopped using that god-awful AssetBundleManager & created my own. I ignored everything I learned in the documentation, and just made a few educated guesses based on the API.

    If I am not mistaken, converting my code is as easy as this:

    From

    Code (csharp):
    1. UnityEngine.Object[] allObjectsBundle1Prefabs = Resources.LoadAll(ObjectPrefabPath);



    To

    Code (csharp):
    1. string AssetBundlePath = Application.streamingAssetsPath + "/AssetBundles/Windows/";
    2. AssetBundle theBundle = AssetBundle.LoadFromFile(AssetBundlePath + "objectsbundle1");
    3. GameObject[] allObjectsBundle1Prefabs = theBundle.LoadAllAssets<GameObject>();


    I think that is correct, or at least a start. I will try it out & see.

    If AssetBundle.LoadFromFile doesn't actually load anything but the manifest file (what is essentially just the paths to the assets), then is there any way to simply call AssetBundle.LoadAllAssetBundles() so I can just store references to all the AssetBundles?
     
    Last edited: Sep 11, 2017
    Deleted User and XCO like this.
  3. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    Yep...That seems to work.

    It was strikingly easy to implement this correctly the moment I completely disregarded everything I read in the Unity docs & just made educated guesses based on the API.

    This really, really infuriates me. How can my clueless use of intellisense resolve an issue that overcomplicated, repetitive, poorly written documentation couldn't?

    All I wanted to do was change my Resources.LoadAll() to theBundle.LoadAllAssets<GameObject>(); & that works perfectly. But nowhere in the documentation was there anything even close to this level of simplicity. Just constant pushes of the AssetBundleManager & how great it is... even though it doesn't even work if your bundles are local.

    Creating the AssetBundles was the only part in the docs that made any sense & was very easy & fast. Especially since it was intuitive enough to understand in the UnityEditor Inspector anyway. Click Click Done.

    I should have done myself a favor & stopped right after just skimming tiny portions of only some parts of the docs, and then just tried to do it all my clueless self.
     
    Deleted User, XCO and Walbert-Schmitz like this.
  4. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    Honestly? Don't use Asset Bundles. What a nightmare. Over 19 hours implementing them already & counting.

    The worst part? The build times - in editor. While in the editor, you have to build your AssetBundles anytime you ever change any assets. It takes forever. Unity provides a "Simulation Mode" but I've yet to see how much time that will take to implement in my own assetbundle manager system. I don't use the trash AssetBundleManager - I created my own system to handle assetbundles & assets.

    If I never came read the Unity "Best Practices" - I would have just continued to use Resources.Load and wouldn't have spent what will inevitably be around 20 hours implementing AssetBundles. What a PITA.

    Best practice my ass.
     
    Deleted User likes this.
  5. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,795
    Deleted User, XCO, 39thstreet and 2 others like this.
  6. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    Well at least I am mostly finished. Finally. 20 hours is a big deal though. For me, unfortunately, that is 1-2 full weeks of gamedev.

    But at least now I am at the same part of my game I was at be....fore.....!!!

    Hehe. Actually I did have a problem where I was loading too much into memory at the start of the game & some of the asset bundle work was making a system which loads/unloads assets to memory at the start of each level. A PITA but it should make memory management easier.

    Now instead of 4GB, it should remain <1GB. I am hoping AssetVariants work effortlessly too. For anyone below 4k resolution, like 1080p, the memory req will be a fraction of that.

    It was the only way I knew to prevent Unity from hitching/lagging when resources were loaded during play / runtime.

    Although some of my GUI still needs to be loaded on demand - not sure how I can prevent the player from seeing any lag while it loads artwork in a book's next page.
     
    shahiro770, XCO and (deleted member) like this.
  7. shahiro770

    shahiro770

    Joined:
    Nov 21, 2017
    Posts:
    2
    Hey, so just to confirm, if you had to choose between Resources.Load, AssetBundles, and AssetDatabase.LoadAssetAtPath(), which one would you use? I'm a bit of a unity beginner, but I still want to try and do what's best.
     
  8. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    For beginners, just stick with Resources.Load(). AssetBundles are a complicated mess really, with questionable worth.

    Stay away from AssetBundles. Maybe even if you're an advanced user.

    Read my quote

     
    AcidArrow likes this.
  9. NicBischoff

    NicBischoff

    Joined:
    Mar 19, 2014
    Posts:
    204
    There are size limits on the resource folder (4gigs) which is why we have to use Asset bundles for larger games.
     
    radiantboy likes this.
  10. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    Of course there is. Not surprising at all with Unity, sigh :confused:
     
    radiantboy likes this.
  11. NicBischoff

    NicBischoff

    Joined:
    Mar 19, 2014
    Posts:
    204
    Sure, Im stating why peeps may choose Asset Bundles over the Resources folder. It's easier to bite the bullet and use them from the start because moving over from Resources to Asset Bundles is a pain.
     
    CarterG81 likes this.
  12. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    Yea, no doubt. A 20+ hr pain for me when I did. Wish I had just done so from the start.
     
  13. radiantboy

    radiantboy

    Joined:
    Nov 21, 2012
    Posts:
    1,633
    Has this ever got easier? I too find it all so confusing, I wish there was an asset to pretty much automate this madness. I only need it to get around 4 gig limit.
     
  14. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    The Editor & General Support forums are pretty crowded. If you want to get info or give feedback about asset bundles and related technology, I suggest you use the dedicated subforum.

    Unity's addressing Asset Bundles being an utter pain by building the Addressables system, which should make things smoother. Info here. Warning; still in beta.
     
    radiantboy and CarterG81 like this.
  15. Jribs

    Jribs

    Joined:
    Jun 10, 2014
    Posts:
    154
    @CarterG81 Also FYI for you and anyone else that came across this post.

    It took me ~30 minutes to recreate the "Simulation Mode" for loading assetbundles straight in the editor.

    It was based off of this snippet from the AssetBundleManager source code
    https://bitbucket.org/Unity-Technol...er.cs?at=default&fileviewer=file-view-default

    Code (CSharp):
    1.  
    2. if (SimulateAssetBundleInEditor)
    3.  {
    4.      string[] assetPaths = AssetDatabase.GetAssetPathsFromAssetBundleAndAssetName(assetBundleName, assetName);
    5.      if (assetPaths.Length == 0)
    6.      {
    7.           Log(LogType.Error, "There is no asset with name \"" + assetName + "\" in " + assetBundleName);
    8.           return null;
    9.      }
    10.      // @TODO: Now we only get the main object from the first asset. Should consider type also.
    11.      UnityEngine.Object target = AssetDatabase.LoadMainAssetAtPath(assetPaths[0]);
    12.      operation = new AssetBundleLoadAssetOperationSimulation(target);
    13. }
    14.  
     
  16. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    Yea, it was easy to do that but that is kindof the problem. Why are these trivial tasks not already part of the default implementation given by Unity?

    Anyway, is this even relevant anymore? Didnt they already replace assetbundles, giving up before even finishing like they always do?

    What a frustrating lesson in futility. I really dislike UT, especially whoever wrote that assetbundles were best practice when they arent and shortly afterwards were on the path to possible deprecation or replacement with another system. You just never know with Unity... you can never rely on them for anything.

    My advice is just pick a version and stick with it until release. Then it doesnt matter what they decide for the future, you're frozen in place. There really isnt any need to upgrade unless you're dying for some new feature, which you really shouldnt be unless you just started your project or are still only messing around.
     
    Last edited: Apr 28, 2019
  17. radiantboy

    radiantboy

    Joined:
    Nov 21, 2012
    Posts:
    1,633
    theyre deprecated??? you sure? and what are we meant to use instead?
     
  18. Jribs

    Jribs

    Joined:
    Jun 10, 2014
    Posts:
    154
    No they are definitely not deprecated yet.

    The addressable system as it is as of April 25 2019 is still very far away from being usable in production.
     
  19. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    The AssetBundle Manager is already deprecated.

    It makes sense that addressables is still very far away from being usable in production, but that they're already planning to replace asset bundles. UT seems to have trouble sticking to just one system, and it really ends up biting developers, especially those who dive right in. Then again ever since the UNET fiasco, I am never surprised and don't trust anything UT does or says. No idea why I thought I'd take them at their word for "best practices" when I originally thought assetbundles would be a good choice to implement. Of course at the worst, I figure I'd just stick with an older version of Unity since implementing assetbundles was such a frustrating mess I don't care how much better addressables is.

    Really it honestly wouldn't surprise me if addressables was replaced with another system before it ever even replaces assetbundles, hahahahaha.... >_>
     
    pimentelj, grubertm and AcidArrow like this.
  20. Just to avoid misinformation and baseless rumor: AssetBundles won't be deprecated any time soon, especially because the Addressable system is being built on the top of the AssetBundles. The AssetBundle Browser is available through the Package Manager.
     
  21. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    I wouldn't call it totally baseless. It's easy for people to get confused when the assetbundle manager is deprecated and UT's awful track record for other systems. Thanks for the correction though. I probably shouldnt be commenting since all my info is grossly out of date and I have 0 faith in anything UT promises. I should turn off notifications for this thread.
     
    Last edited: Apr 28, 2019
  22. arkogelul

    arkogelul

    Joined:
    Nov 14, 2016
    Posts:
    105
    So this best practice advice to use Asset Bundles over Resources.Load isn't valid ?
    I'm having weird hiccups on instantiating some assets at runtime, and I was thinking it was because of using Resources.Load, but I'm wondering if that's the case after reading this thread.
     
    CarterG81 likes this.
  23. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    From my discussions with other Unity developers on discord, Unity's advice on best practice is not necessarily best practice. They suggested I stick with Resources.Load() unless I needed it, and I have for my other projects without issue.

    Asset Bundles are a pain to implement and maintain. Resources.Load() is effortless. The features of asset Bundles are nifty but only if you actually need them.

    What I would do is stick with Resources.Load() until you absolutely need AssetBundles. If you're not doing anything too complicated and dont need asset bundles, then definitely just Resources.Load().

    If later you need to implement assetbundles for the feature, you can always add it later. Resources.Load() is so easy, youre not gonna lose much time sticking with that and it wouldnt give you much trouble replacing it.
     
  24. aer0ace

    aer0ace

    Joined:
    May 11, 2012
    Posts:
    1,513
    AssetBundleManager and AssetBundles in general have definitely been a pain. I particularly hate that Unity Technologies deprecated the ABM and don't have anything production ready in its place. I just finished up an article about using the AssetBundleManager. I wrote the majority of it last year, but never finished it until now, because I thought that maybe Addressables would already be ready for production. It's true that AssetBundleManager has a lot of problems with it, but at least it's something, until Addressables get to a more usable state.

    EDIT:
    I felt compelled to add a little more after having fully read the thread. I completely agree with @CarterG81. The communication in the Unity docs regarding Resources.Load() is completely misleading. They should definitely remove that "Don't use it" in bold letters. It's actually pretty insulting to the rest of their software. There are loads of features of Unity that are super easy to use, and then there are these half-ass solutions that have docs attached that say, don't use this thing that a majority of game devs use? That's insane.

    My advice to beginners is to use Resources.Load(), or even direct reference prefabs until UT gets their sh*t together with AssetBundles and Addressables. It may be good to read up on those, but implementing them will definitely impede your forward learning progress for weeks if not months.Transitioning from Resources to AssetBundles or Addressables should be done only if you plan to release commercially, and if so, can be done late into production, if/when you run into performance hiccups, or need to deploy to different platforms with different asset requirements, or if you plan to add over-the-internet patching support.

    Personally, it took me a few months to get to a point that my asset iteration efficiency was not severely impacted by AssetBundles after integrating it into my game. I slightly regret doing it, only because I'm already on the other side. And if it were not for my custom tools that make AssetBundle and build deployment easier, I probably would have killed myself by now.
     
    Last edited: Aug 6, 2019
    bobisgod234, radiantboy and CarterG81 like this.
  25. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    It is very refreshing to see I am not alone in this. Thanks for the added edit and vindication.

    UT seriously needs to edit that documentation, as you suggested. Removing their suggestions entirely to "not use Resources.Load", or at the very least not having it in bold for god's sake! (And add a caveat).

    What annoys me the most is that many users wont find this thread until AFTER they've already wasted enormous amounts of time on AssetBundles. Ergh!
     
    pimentelj likes this.
  26. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    Have you looked into pre-caching your objects? Instantiating them on load (first thing) so you can avoid instantiating them during Play?

    You only need to instantiate 1 object for Unity to load all its necessary textures, assets, etc.

    On one of my games I preload 1 of every prefab I use in a scene. Since my game is 2D & each scene/level is it's own biome, this makes it easy enough, and saves me from any hiccups loading their textures later.

    On another of my games, a pixel art 2D game, I literally just load literally everything into memory at the start of the game. This isnt an issue because characters are extremely tiny. A character is just a 2.0kb texture.

    There is also object pooling, which is where you instantiate more than you'll ever need and then reuse the same game object over and over. So an enemy ship the player destroys in 1 hit would have its gameobject disabled, not destroyed, then reset everything, and to spawn another reuse that same gameobject (now enabled).

    In my games though, it is the texture loading that kills performance for me.

    I believe Unity also now has asynchronous loading too? Might want to look into that as well. Been awhile for me.
     
  27. Shushustorm

    Shushustorm

    Joined:
    Jan 6, 2014
    Posts:
    1,084
    Thanks for the rant. I already implemented a system that was based on the assumption that I would use Resources, but then I read the docs, which were heavily discouraging this with the suggestion of using AssetBundles instead. I was confused, because of the explicit hate Resources got.
    But I didn't understand the reasoning behind that. At all.
    So I decided to stay with Resources.

    Personally, I have a huge database and I only need to load very granular parts of data. For example, when I need to load an icon of an item, I only need that. Not all the other assets associated with that item, because that would make inventory loading an absolute mess. At the same time, bundling assets together is the whole core of using AssetBundles. Why that would be preferred in any scenario besides the very specific use cases of delivering content via web or a patch, I don't know. I am not loading content via web. I am not planning on delivering any DLCs. I just want to ship a game. A finished one that is. And AssetBundles really seem to waste time. Not just their implementation, but if you have to additionally create a bundle for each granular piece of data that you want to load seperately, that's just insane.

    I'm glad I found this topic. Not going to use AssetBundles. Or Addressables. Why needlessly weaken workflow efficiency?
    The only aspect that I wasn't aware of is the 4GB limit. Is this still recent?

    Also, there seems to be some interest in automatically creating AssetBundles to make use of the doubtfully better performance. Personally, I would much prefer if you leave it to the user if AssetBundles should be used or not. I don't want to load things that I don't need.
    I would rather wait a few seconds on application start than half a second each time when opening the inventory in a new scene. Opening an inventory should be fast. It's frustrating if it isn't. And I don't want to cache all the possible icons, most of which very much not needed most of the time, in RAM by using Inspector references.
     
    Jingle-Fett likes this.
  28. Blenderik

    Blenderik

    Joined:
    May 14, 2013
    Posts:
    146
    In my experience (8 years) both versions have their merits. I did not check differences in RAM and loading times.
    @Shushustorm mentioned downloading, there they are the only option, except textures directly as far as I can think of.

    Problem with assets:
    - You need to create them, worst case even for each platform individually.
    - You need to manage their loading/unloading and all that stuff.

    Problem with resources:
    - You have to ship them all for each build.
    - You have to re-compile when you make changes to the Resources folder
    - 4GB limit on assets

    We are running an build in-house and when I want to add models to the current version I just follow my naming convention and add them to the AssetBundle folder we use.
    We are offering a WebGL version of the same project that I want to keep as lean as possible, so I only put the essentials in the build and then download the rest either on demand or in the background once the initial start of the WebGL app is complete.
    At this point if I were to keep Resources for the Standalone build and use assets for WebGL, I would have to manage build options that are heavily different for each plattform. Using assets, all I need to do is manage where the asset comes from.

    In versions shipped to 3. party you could still enable in-game downloads where again you only need to manage the asset bundles on your server and can easily extend your content.

    In conclusion: Small stuff and few items, I would definetly prefer Resources.Load, once it gets complicated, downloads are involved etc. really consider switching to AssetBundles.

    Why Unity is pushing them so hard, I don't know. Maybe make sure they do not go unnoticed?
     
  29. tadsavage

    tadsavage

    Joined:
    Jan 13, 2018
    Posts:
    2
    @Blenderik
    Thanks for suggestion. When you say small stuff and few items - how many assets would you say is manageable?

    Also - for Scriptable Objects - does anyone know if having.... say 500 in Resources is too many?
     
  30. NicBischoff

    NicBischoff

    Joined:
    Mar 19, 2014
    Posts:
    204

    Scriptable objects are just text files but if they reference assets in the resource folder then you would need to consider that.