Search Unity

Simpler Alternative to Addressables.

Discussion in 'Addressables' started by locus84, Feb 3, 2020.

  1. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    After using Addressables for a month,
    I finally end up using my own implementation which utilizes ScriptableBuildPipeline.

    Folder based.
    No fancy UI & functionalites.
    Not so much settings to tweak.
    Straightforward.
    supports sync API as well as memory management.
    MIT.

    Repo : https://github.com/locus84/Locus-Bundle-System
    *New* Discord : https://discord.com/invite/kfVzV7qaEF

    Even if it does not fit on your project, I think you can easily make some changes to fit on yours.
    Currently it's only for my general purpose.

    But feel free to make an advices, general feature requests, suggestions... etc.
    Thank you.




    -----------------------------------------------------------------------------

    Hi guys, 1.0.5 version is out with a few improvements.

    1. [update] added "open" button for each bundle output folder.
    2. [update] added functionality to log duplicate assets in bundles.
    3. [update] added 'dry build' functionality to get log file in #2 without actually building bundles.
    4. [fix] fix file path for some editor/runtime platforms(thx to petitbas).


    -----------------------------------------------------------------------------

    Hi guys, 1.0.6 version is out with a main feature

    1. [Add] Auto shared bundle generation. <---**this**
    2. [Remove] Remove dry build as shared bundle will replace it's functionalities
    3. [Fix] Miner improvements in code structure.


    -----------------------------------------------------------------------------

    Hi guys, 1.0.7 version is out with some minor improvements

    1. [add] Added providing subset of bundle names when downloading/measuring.
    2. [add] BundleManager now have TryGetCachedManifest fucntion to support offline play
    3. [remove] DownloadAssetBundles function now does not accept 'hardUnload' parameter. it will be always false to keep loaded assets safe.

    -----------------------------------------------------------------------------

    Hi guys, 1.0.8 version is out with a fix.(might be critical for some users)

    1. [Fix] fixed includeSubdir option is building weird asset path (thx to Paul_H23@Unity forum)

    -----------------------------------------------------------------------------

    Hi guys, 1.0.11 version is out with some minor improvements, and fixes

    1. Fix) Possible wrong directory seperator usage on some platform
    2. Fix) TrackingOwner function throws error when it's in assetdatabase mode.
    3. Change) Updated ScriptableBuildPipiline dependency version to latest
    4. Add) Paste button added in Assetbundle set UI.

    Now you can easily bundle assets in Packages folder.

    -----------------------------------------------------------------------------

    Hi guys, 1.0.12 version is out with a lot of improvements!!

    Fix) Scene loading inside subdirectory now works properly.
    Fix) Undo in AssetBundleSettings now updates inspector ui immediately.

    Improvement) Added EditorAssetMap, which handles AssetDatabase Usage inside Editor.
    Improvement) When building, if no manifest found, it automatically shows a popup that asks you if you want to build local bundles now.
    Improvement) Now support EditorTest, call BundleSystem.BundleManager.SetupApiTestSettings before calling apis in non-playing mode.
    Improvement) Added BundledAssetPath, helps you specify asset path inside bundle.
    Improvement) Added several informative exceptions.
    Improvement) Performance gain as it does not cache asset path right after loading bundle.


    change) now this package supports unity 2018.4 or higher, dependency scriptablebuildpipeline's version is now 1.15.1

    None of api has been changed. feel free to update!

    ---------------------------------------

    Hi guys, 1.0.13 version is out with a fix.

    Fix) loading scene in assetdatabase mode throws unexpected exception while the scene is actually loaded without problem.

    ---------------------------------------

    Hi guys, 1.1.0~1.1.2 version is out with a few fix and improvements

    [improvement] Added helpful exceptions for tracking errors
    [improvement] added IBundledAssetPath. you can create your own struct to support releted functions.
    [fix] Trackinng functionality inside some loading api now handles null properly
    [fix] Shared bundle now properly distinguish scene embeded prefab instance
    [fix] Fix for subfolder checking
    [fix] Subset bundle dependencies are not collected properly. (thanks to Starpaq2@UnityForum)

    --------------------------------------

    Hi guys, 1.1.3~1.1.4 version is out with some fixes.

    [fix] loading scnee async from subfolder is not working properly
    [fix] bundle can be reloaded while loading async, causes unexpected behaviour.
    [fix] scene inside subfoler object tracking is not working normally.

    ---------------------------------------

    Hi guys, 1.1.5 version is out with some fixes.

    fix) compilation error when using unity 2018
    fix) directoryseperatecharacter issue on some platforms
    improvement) now there's save scene popup when building assetbundles.
    Confirmed it's working on webgl platform(thanks to @nichjaim)

    ---------------------------------------

    Hi guys, 1.1.6~1.1.7 version is out with some improvements.
    fix) combine path function doesn't support android platform
    improvement) added ability to safely cancel Initialize, GetManifest, Download functions.
    improvement) upgraded scriptablebuildpipeline to 1.19.1

    ---------------------------------------

    Hi guys, 1.1.9 version is out with a fix and improvements
    improvement) domain reload disabled support
    improvement) compare equality interface and operators into BundledAssetPath
    fix) broken prefab links after WriteExpectedSharedBundles

    ---------------------------------------

    Hi guys, 1.1.10 version is out with some improvements
    improvement) added support async-await for BundleAsyncOperations and BundleRequest<T>.
    improvement) handle UnityWebRequest.result to suppress warnings in higher version of unity.
     
    Last edited: Nov 28, 2021
  2. travelhawk

    travelhawk

    Joined:
    Jan 13, 2017
    Posts:
    22
    Sounds interesting. Does this support local caching? Means if the player downloaded it once, is it still there without internet connection?
     
    Soniksz likes this.
  3. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    Yes, of cource, It caches downloaded assetbundles except you provided with your build(which you can simply load from local).

    Means you can download and cache your bundle as usual, as well as provide subset of your bundles with your build and update later on if needed.
    This is very good for making your all your UIs to assetbundles, you don't need to load font assets twice.
    Just add font and initial UIs as your local bundle, and provide with your build.
     
  4. davidrochin

    davidrochin

    Joined:
    Dec 17, 2015
    Posts:
    72
    Hello! Have you released a game using this system?
     
  5. chanon81

    chanon81

    Joined:
    Oct 6, 2015
    Posts:
    168
    Wow, this looks very interesting. Thanks for sharing! I might look into using it.
     
  6. stevenchristian20

    stevenchristian20

    Joined:
    Dec 23, 2019
    Posts:
    29
    Looks great I will check it out!
     
  7. CrispyCritter

    CrispyCritter

    Joined:
    May 11, 2018
    Posts:
    19
    This looks like just what i need ill give this a test
     
  8. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    I've been using this from my last company project which is released on iOS and Android. It's not the completely same, but almost identical except Local bundle and UI support.
    Currently my personal project and my friends' project are using this either.
     
    Last edited: Mar 10, 2020
    phobos2077, davidrochin and chanon81 like this.
  9. MN-US

    MN-US

    Joined:
    Dec 5, 2018
    Posts:
    1
    That looks really exciting - been struggling quite a bit with the not so straightforward Addressable system..

    A few questions:
    Are you able to solely make use of a local folder to read/write the bundle system from? We're making use of a system, where all cached elements are being put into the PersistentDataPath and then loaded from there.
    If we had a bundle with a scene, containing a handful of models, with associated meshes, materials and textures, is it possible to load all assets in one swoop, or would be needed to call LoadAll<GameObject>, <Material> etc prior to loading and instantiating the given scene?

    Thank you!
     
  10. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    Thank you, btw, what brings you here? I'
    If you have a scene contains everything u need, then just loading that scene is enough.
    This pulgin does not utilize PersistentDataPath, all the local bundles(shipping with build) are in StreamingAssets folder.
    Otherwise it uses cache folder that operating system provides.

    For an example you ship Bundle A with your build then
    Build(+A)
    If you update A to A1 and patch,
    Build(+A) CacheFolder(A1)
    If you provide more contents named B
    Build(+A) CacheFolder(A1+B)
    If you change contents of both A, B to A2, B2
    Build(+A) CacheFolder(A2+B2)
     
  11. chanon81

    chanon81

    Joined:
    Oct 6, 2015
    Posts:
    168
    Well, I still have no idea how to setup Addressables for downloading remote asset bundles and I still feel that it is too buggy to rely on. Your solution has been used in released games, so I'm thinking it might be more solid. Also it supports Sync API which could really help simplify things.
     
    locus84 likes this.
  12. CrispyCritter

    CrispyCritter

    Joined:
    May 11, 2018
    Posts:
    19
    I am running some tests now, my project i am about to start will have large models like 150MB each and theres going to be about 10 of them but also more will be added in the future we plan to have a UI that will allow the user to select what models they want to download and store.

    Will this system work for that? also does this work on IOS and android?.

    I am playing with this today but figured i would ask the question.
     
  13. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    Yes, it's possible.
    And it works on both android/ios.

    If you want to download portion of assetbundles, you have to do some work.
    By default, GetManifest function in BundleManager class will return list of all possible bundles,
    you have to select which bundle to download, and pass it to DownloadAssetBundles function in BundleManager.
    Note that DownloadAssetBundles deletes bundles not listed in Manifest.
    So for example, Your game need bundle A, B, C as it's default functionalities, and user granted DLC named D.
    your manifest should contain union of two list. (A,B,C,D). if you pass only (A,B,C) then it'll remove cached D file.
     
    andreiagmu likes this.
  14. CrispyCritter

    CrispyCritter

    Joined:
    May 11, 2018
    Posts:
    19
    My plan is to use scriptable object for the core application data, this will be local but contain settings for bundles or in my case 3D models.

    THere will be a UI for the user and they will be able to select what model to download also it would have the option to remove the downloaded bundle and they can re download it in the future.

    So far your system is working great i have a simple model thats 73MB and your system does an amazing job of download and setting up things needed to spawn.

    I do have a question i see you give a progress on the download but would there be much work get to get MB downloaded? or is it just simplier to show a % progress rather then 1MB of 73MB complete.
     
  15. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    You can do both, there are progress, currentCount(current index), and CurrentlyLoadingFromCache in BundleAsyncOperation.
    And currentCount is just the index of bundle in the manifest.
    you can easily match it's size to it's index.

    And by checking CurrentlyLoadingFromCache, you can figure out whether it's loading from cache or it's downloading.

    In short, while downloading, match index with currentCount, and if CurrentlyLoadingFromCache is false, let' user know that it's downloading and currently downloaded size is Progress * Size

    By the way, if currentCount is -1, it means the download function has not started to iterating bundle list.
     
    Last edited: Mar 11, 2020
    andreiagmu likes this.
  16. rooster

    rooster

    Joined:
    May 22, 2009
    Posts:
    21
    I'm looking for a simple way to load custom content into a mobile app. This would be personalized content for each user that was built beforehand for them but after the app is released. Ideally, I want to be able to build one app and use a simple code to download the content. E.g. by loading a specific bundle by name. Would I be able to use your system for this or can you recommend an alternative?
     
  17. Starpaq2

    Starpaq2

    Joined:
    Mar 14, 2013
    Posts:
    77
    A huge thanks to locus84. This has saved my project. I'm guessing the addressable system may be efficient for large teams and complex pipelines. And nothing against the team developing addressables. However, the simplicity of workflow, code structure and extend-ability has saved my project. I was also able to create a simple key reference system based on string variables as well.

    I was able to convert from addressables in one day. I was having problems with dependencies, cache management and the catalog. All of this was easily solved and integrated with LocusBundle. As an indie I value simplicity and the least amount of dependency to reduce problems for a live production.

    Anyone considering an alternative and worried about lost development time. Its worth it. I regret originally avoiding it until i ran into further issues with the current package.
     
    andreiagmu, ejx61s, lclemens and 6 others like this.
  18. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    it's ok. but if you wanna make contents and provide after it's release, you have to update your app binary as long as you want to update your scripts(or use stripped class). You can actually disable stripping but it'll increase you build size. What I recommend is include at least one default content that ships with your build(actually it's ok to only exist when building remote bundles) so stripping would not bother you. other than that, I think this system can help you.
     
  19. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    Thank you for the recommendation.
    You made my day :D
     
  20. CrispyCritter

    CrispyCritter

    Joined:
    May 11, 2018
    Posts:
    19



    So far i have this setup, how would i get about getting the size of just say the remote PumpModel?

    this code will give the size of everything together
    Code (CSharp):
    1.         //get download size from latest bundle manifest
    2.         var manifestReq = BundleManager.GetManifest();
    3.         yield return manifestReq;
    4.         if (!manifestReq.Succeeded)
    5.         {
    6.             //handle error
    7.             Debug.LogError(manifestReq.ErrorCode);
    8.         }
    9.  
    10.         Debug.Log($"Need to download { BundleManager.GetDownloadSize(manifestReq.Result) * 0.000001f } mb");
    The above code works but gives the size of the entire bundles combined, i am not sure the code needed just to get one bundle size or download a simple bundle
     
  21. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    Code (CSharp):
    1.  
    2. var manifestReq = BundleManager.GetManifest();
    3.         yield return manifestReq;
    4.         if (!manifestReq.Succeeded)
    5.         {
    6.             Debug.LogError(manifestReq.ErrorCode);
    7.             yield break;
    8.         }
    9.  
    10.         var downloadReq = BundleManager.DownloadAssetBundles(manifestReq.Result);
    11.  
    12.         while(!downloadReq.IsDone)
    13.         {
    14.             if(downloadReq.CurrentCount >= 0)
    15.             {
    16.                 var currentBundle = manifestReq.Result.BundleInfos[downloadReq.CurrentCount];
    17.                 if(!downloadReq.CurrentlyLoadingFromCache)
    18.                 {
    19.                     //you're downloading
    20.                     var bundleName = currentBundle.BundleName;
    21.                     //bytes downloaded is
    22.                     var downloadedSize = currentBundle.Size * downloadReq.Progress;
    23.                 }
    24.             }
    25.             yield return null;
    26.         }
    27.  
    28.         if (!downloadReq.Succeeded)
    29.         {
    30.             Debug.LogError(downloadReq.ErrorCode);
    31.             yield break;
    32.         }
    33.  
    Hope this helps
     
    lclemens and CrispyCritter like this.
  22. CrispyCritter

    CrispyCritter

    Joined:
    May 11, 2018
    Posts:
    19

    That is fantastic, thank you so much for your support in this, if you ever put this great asset up for sale we will be the first to buy it :)
     
    davidrochin and locus84 like this.
  23. CrispyCritter

    CrispyCritter

    Joined:
    May 11, 2018
    Posts:
    19
    how could i adotp the above to to check if it needs to download or its cached without starting an actual download.

    I am back again with further questions, i am sorry to keep pestering you.

    With your code am i right in saying you have to start the download process in order to tell if ifs cached or not?

    at the moment i have a UI list that displays a list of bundles and there size but not sure how to checked is its the latest version or cached.

    Sorry for my noobie questions i have not used asset bundles before untill now so this is a bit of a learning curve for me as in managing remote assets in general.

    Code (CSharp):
    1.         var downloadReq = BundleManager.DownloadAssetBundles(manifestReq.Result);
    2.  
    3.         while (!downloadReq.IsDone)
    4.         {
    5.             if (downloadReq.CurrentCount >= 0)
    6.             {
    7.                 var currentBundle = manifestReq.Result.BundleInfos[downloadReq.CurrentCount];
    8.                 if (!downloadReq.CurrentlyLoadingFromCache)
    9.                 {
    10.                     //you're downloading
    11.                     var bundleName = currentBundle.BundleName;
    12.                     //bytes downloaded is
    13.                     var downloadedSize = currentBundle.Size * downloadReq.Progress;
    14.                     // Debug.Log(downloadedSize / 1024);
    15.                     Debug.Log($"Need to download { currentBundle.Size * downloadReq.Progress * 0.000001f } mb");
    16.                 }
    17.             }
     
  24. Starpaq2

    Starpaq2

    Joined:
    Mar 14, 2013
    Posts:
    77
    I had to create and extend a bit of of the code to specify a method exlcusively to check for the cache of a single bundled folder. It worked out very well.

    I'm not at my main computer now. But this may possibly help you get further.
    Look into the BundleManager.cs file and starting from line 290 you will see how to this system determines the cache.
    https://github.com/locus84/Locus-Bundle-System/blob/master/Runtime/BundleManager.cs


    here is the snippet:
    Code (CSharp):
    1.                 result.SetCurrentIndex(i);
    2.                 var bundleInfo = remoteManifest.BundleInfos[i];
    3.                 var localBundle = s_LocalBundles.TryGetValue(bundleInfo.BundleName, out var localHash) && localHash == bundleInfo.Hash;
    4.                 var isCached = Caching.IsVersionCached(bundleInfo.AsCached);
    5.                 result.SetCachedBundle(isCached);
     
  25. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    BundleManager.GetDownloadSize(manifestReq.Result) gives to total byte size need to download in the manifest you passed. If it returns zero, then you have nothing to download.
    But but you still have to call DownloadAssetBundles as it'll load cached bundles to use right away.

    @Starpaq2 Do you think it's needed often? I'll add it if you say so.
     
  26. Starpaq2

    Starpaq2

    Joined:
    Mar 14, 2013
    Posts:
    77
    @locus84 Hard to say, I am using it for a few non-game projects that require an indication to the user what has been downloaded. The user interface for my projects are usually tied directly into the availability of the bundles local or remotely. Especially on storage limited platforms such as mobile and mobile vr (oculus).

    This probably is not nearly as practical for in game/level streaming.

    I am planning to see if i can extend the system to use a multiple manifest by linking them to a master-catalog manifest. That way if the library gets really large I can use multiple assetbundle files(scriptable objects). It's not a necessity but I have no idea what limitation I can run into with 100's of folders/bundles as the product expands with more content during production. I'll find out.
     
  27. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    Let me know I you find any improvement point when you hit 100ish bundles :D

    About multiple manifest, how's just adding tags to each bundle so user can define tag?
    Then downloading assetbundle function have additional input parameter something like
    "interested tags" and download all the bundles containing tags including their dependencies.
    if no tag is provided, load/download everything as usual.

    Actually I don't want to provide full control of each bundle, users should not care about it's dependencies, load order...etc. Lots of Unity newbies are overwhelmed by Addressable system(No offence). Looking at Unreal's Package system, it's way simpler than Unity's one.

    Btw glad to see the framework applied to your multiple project.
     
    Starpaq2 likes this.
  28. caochao88_unity

    caochao88_unity

    Joined:
    May 16, 2019
    Posts:
    26
    what's your strategy to handle duplicate bundle dependecies? I mean when assigning different folder to different bundle, maybe they have duplicate dependecy.
     
  29. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    AFAIK it's controlled by ScriptableBuildPipeline, for my experience, If A, and B bundle contains same C dependency, It's included in A when building A first, and B has dependency on A, if you seperate C though, you have A, B both dependent on C, while playing, it's okay as it loads up every bundle in memory(only headers to maintain low memory usage).
     
  30. caochao88_unity

    caochao88_unity

    Joined:
    May 16, 2019
    Posts:
    26
    maybe you could provide an anylazer like addressables system does.;)
     
  31. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    Good idea, currently I just look for bundle build logs if there's unexpected bundle referencing. but if one bundle isn't too long, it wasn't a big deal :D. Thank you for the advice!
     
  32. caochao88_unity

    caochao88_unity

    Joined:
    May 16, 2019
    Posts:
    26
    another question, what's your implementation of loading assetbundle synchronously? it's by preload all assetbundle before loading certain assetbundle?
     
  33. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    All the bundles(header only) are loaded in initializing/downloading steps, simple. After then, there's no assetbundle loading. But there's an exception, if you enable AutoRealodBundle, it'll fire assetbundle loading in the background if an assetbundle reference count is zero and unload existing/swap to new one when it's done, to keep memory footprint low.
     
  34. CrispyCritter

    CrispyCritter

    Joined:
    May 11, 2018
    Posts:
    19
    I am making progress, so i am still in R&D mode, this is what i setup so far.

    my asset bundles are setup like so
    My first bundle has the main application dataset these are scriptable objects

    the next set of bundles i have broken up into model sets
    so bundle02 has one large gameojbect
    bundle03 has another large gameobject

    but i will still stuggling to download a single bundle ready to pull assets out of it.

    bundle01 contains the main app data and structure this also contents the names of the bundles so with this i can get the bundle names but still stuggling as to how i would do a check on that single bundle as the user will be able to select a download button i dont really want this to start downloading first.

    before i layout the UI i of course need to check weather the user should be shown a download button or a tick to say this asset is already downloaded and no updated needed.

    Maybe i am just doing this wrong :(
     
  35. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    All you asked are easily done by modifying manifest itself.
    There is a field named BundleInfos as a list so you can add/remove bundles you interested.

    1. App starts.
    2. Get manifest by GetManifest()
    3. Store Manifest.BundleInfos somewhere.
    4. Assign new list to Manifest.BundleInfos.
    5. Add bundles you interested by iterating bundlelist stored(at 3).(in your case, bundle name with selected model and base data)
    6. Call GetDownloadSize and if it's zero, call DownloadAssetBundles() and load Model
    7. if it's not zero, Ask user if he/she wants to download.
    8. if user hit 'Yes' Button, call DownloadAssetBundles() and load Model.

    My apologies, I can't elaborate more than this.
    If you can't understand, just provide some of your code structure.
    Or I can teamviewer you in weekend.
     
    CrispyCritter likes this.
  36. CrispyCritter

    CrispyCritter

    Joined:
    May 11, 2018
    Posts:
    19

    Magic i got it now, i feel i have full control over how i want this to work. i can be a bit slow some times to learn these things but does tend to pay off, god i love your system i done for questions i can pretty much just crack on now i would share my code but i feel its a bit hacky lol.

    Thank you for your offer to teamviewer this means allot i will not need it now as i have solved my problems oh and just to add your level on support of this is better then most paid products :) have you concidered putting this on the asset store?
     
  37. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    Great! hope you can complete your project without an issue.
    About assetstore, I think I won't change it's licence. I want Addressables improve it's usability as much as newbies can use it. Until then, this will be left as simpler alternative. :D
     
    andreiagmu and CrispyCritter like this.
  38. RogueCode

    RogueCode

    Joined:
    Apr 3, 2013
    Posts:
    230
    This is great, and super simple. Managed to get things loading in minutes, and it seems to all make sense. I'm also getting significantly faster loading than with addressables.

    Would you mind explaining how to regain memory?
    I'm spawing objects with it, but I'm not sure how to clear them afterwards.

    Code (CSharp):
    1. var parent = BundleManager.Load<GameObject>("All", item);
    2. var obj = BundleManager.Instantiate(parent);
    3.  
    4. ... do some stuff
    5.  
    But then when I Destroy(obj) or Destroy(parent) (or both), it seems to only count down the "Tracking Owner Count" but not the object count. And memory stays high.

    Thanks!

    EDIT:
    I was being dumb, there is a perfect example right here: https://github.com/locus84/Locus-Bu...s~/Sample/ApiSampleScript/SampleTitleScene.cs
    For anyone reading this - just release the parent as soon as you're done with it (in my case above that would be right after instantiating it in the scene).

    However I do have a different question now. When I hit play before any asset loading stuff my scene memory is (yellow text):
    upload_2020-4-6_23-3-39.png


    But after loading all my objects, destroying them, and seeing both the tracking object count and owner count return to zero it is still:

    upload_2020-4-6_23-4-5.png

    It there anything I need to clean up beyond the following:
    - releasing the original loaded object
    - destroying the instantiated gameobject
    ?

    Is it maybe that the actual bundle needs to be released or something?

    Thanks!
     
    Last edited: Apr 6, 2020
  39. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    Hi there, glad to see you like it!.

    As you know if reference count hits zero, it reload assetbundes async and swap with existing one.
    You can track that by enabling logging.

    And those reload functionality only works when you enable AutoReloadBundle in Initialize function.
    Also if you don't simulate Assetbundle it in the editor, it won't unload bundles as it's not actually use Assetbundle. It uses AssetDatabase Instead.

    Plus if you load a scene, all scene root game objects are tracking and scene itself is tracking either. it'll unload if the scene is unloaded and all the root gameobject are destroyed too.
     
    Last edited: Apr 7, 2020
    andreiagmu and RogueCode like this.
  40. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    For those who don't want to care about Memory management.

    This framework does not force you to use Reference based Auto reload feature.

    Just disable it in BundleManager.Initialize method, and call Resource.UnloadUnusedAssets() as you've done before with Resources folder.
     
  41. RogueCode

    RogueCode

    Joined:
    Apr 3, 2013
    Posts:
    230
    Out of interest, why is this a reload? As in, I see that it unloads the old one, but why does it _always_ load up a new one? Is this to stop having to call initialize again when you don't specifically know whether the old bundle got unloaded?
     
  42. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    This is how this framework can take advantage of memory management as well as provide synchronized API.
    To provide synchronized api, there must be an available assetbundle. So in background, it fires a fresh www request to obtain new assetbundle(async), and when it's done, it check if there's still no reference, and replace old bundle(which holds loaded memory) to new bundle(does not hold memory except headers). So when unloading old bundle, it frees up memory, and swapped new bundle can provide synchronized api right away after swap.
     
    andreiagmu and RogueCode like this.
  43. GamePro

    GamePro

    Joined:
    Jul 16, 2012
    Posts:
    36
    Dear Locus84,
    I am working on a game where i have to download the 3d contents + videos and audios and images. these are not AssetBundles.

    --- Workflow ---

    1. User Installed the Game.
    2. At first it will download all the data from cloud and the game will read ison files. and load that data.

    All these json files and 3d models and audios + videos are not asset bundle.

    My Question is can i user your Framework for this ?
    Do you have any Suggestion for me. ?

    please guide me for best solution.

    regards
     
  44. Spy-Shifty

    Spy-Shifty

    Joined:
    May 5, 2011
    Posts:
    546
    @locus84 thank you for this amazing package.

    I made some initial test with it to verify if this one fits into my project. An I have to say. It's very easy and straight forward . The API is slim and clear wherefore it's super easy to extends. I like it:)

    One thing you could implement is async operation.

    And there is a small issue/bug with your asset naming. The prefix should be build by subdir.name not by dir.name ;)

    MyAsset
    + Folder1
    +-- Cube.prefab
    +Folder2
    +-- Cube.prefab


    In current verison the resulting name for both assets would be "MyAsset/Cube"
    With the subdir prefix you would receiver "Folder1/Cube" and "Folder2/Cube"

    I've also implemented a cached version of the manifest for remote bundles.
    It's usefull if you don't have an active internet connection.
     
  45. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    You better build your own system.

    Mine is just for assetbundles.

    Things might much easier if you have some import plugin for those assets.

    My suggestion is...

    1. Build your asset catalog with json which contains downloadable contents list and it's hash.

    2. Fetch that catalog when app startup.

    3. Download them, save it to persistant data path. if there's no corresponding file in that path. (or hash is not the same-means asset is updated)

    4. import from persistant data path.
     
    pahe likes this.
  46. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    Glad to see you find it useful!

    I'll check the bug you mentioned :D

    For async/await support, I think ppl who want it can implement on their own, lol.
     
    Spy-Shifty likes this.
  47. petitbas

    petitbas

    Joined:
    Sep 9, 2014
    Posts:
    17
    When I run this code in the editor I always get "0mb" to download:

    Code (CSharp):
    1.         //get download size from latest bundle manifest
    2.         var manifestReq = BundleManager.GetManifest();
    3.         yield return manifestReq;
    4.         if (!manifestReq.Succeeded)
    5.         {
    6.             //handle error
    7.             Debug.LogError(manifestReq.ErrorCode);
    8.         }
    9.  
    10.         Debug.Log($"Need to download { BundleManager.GetDownloadSize(manifestReq.Result) * 0.000001f } mb");
    How can I test querying the manifest and downloading single assetbundles in the editor?
     
  48. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    upload_2020-5-13_10-49-43.png

    It's easy, please refer above screenshot.
    You may take a look quick start video I've uploaded to youtube.
     
    laurentlavigne likes this.
  49. petitbas

    petitbas

    Joined:
    Sep 9, 2014
    Posts:
    17
    I went back and re-did all the steps on a windows 10 machine and things run fine there. However, I usually develop on a Mac which was giving me this error:
    Code (Boo):
    1. Do Initialize first
    2. UnityEngine.Debug:LogError(Object)
    3. BundleSystem.<CoGetManifest>d__96:MoveNext() (at Library/PackageCache/com.locus.bundlesystem@2cc879c0a94175c86d3807f83194fa6a94254209/Runtime/BundleManager.cs:201)
    4. UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
    5. BundleSystem.BundleManager:GetManifest() (at Library/PackageCache/com.locus.bundlesystem@2cc879c0a94175c86d3807f83194fa6a94254209/Runtime/BundleManager.cs:193)
    6. <Start>d__0:MoveNext() (at Assets/Scripts/TitleScene.cs:10)
    7. UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr) (at /Users/builduser/buildslave/unity/build/Runtime/Export/Scripting/Coroutines.cs:17)
    8.  
    9. NotInitialized
    10. UnityEngine.Debug:LogError(Object)
    11. <Start>d__0:MoveNext() (at Assets/Scripts/TitleScene.cs:14)
    12. UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr) (at /Users/builduser/buildslave/unity/build/Runtime/Export/Scripting/Coroutines.cs:17)
    13.  
    On this line in TitleScene.cs:
    Code (CSharp):
    1. var manifestReq = BundleManager.GetManifest();
    That's with "Emulate in Editor" and "Clean Cache in Editor" on.

    No idea why it fails on Mac os.
     
  50. locus84

    locus84

    Joined:
    Mar 30, 2011
    Posts:
    119
    Hi there!

    Can you check below?

    1. You built Local build and remote build.(local is needed as we need a manifest shipped.)
    2. You initialized before calling 'GetManifest' function.