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

The AssetBundle Manager Tutorial Q&A

Discussion in 'Community Learning & Teaching' started by Adam-Buckner, Sep 11, 2015.

  1. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    but

    AssetBundleManager.SetSourceAssetBundleURL("http://www.mysite.com/AssetBundles/OSX")

    run through

    Code (csharp):
    1. public static void SetSourceAssetBundleURL(string absolutePath)
    2. {
    3.     BaseDownloadingURL = absolutePath + Utility.GetPlatformName() + "/";
    4. }
    without an initial trailing slash would give you...

    http://www.mysite.com/AssetBundles/OSXOSX/

    not

    http://www.mysite.com/AssetBundles/OSX/OSX/

    ....

    no?

    That would need... absolutePath+ "/" + Utility.GetPlatformName() + "/";

    to work I think. What do the Logs say for the requests? are they not /OSXOSX/ thus failing?
    (full disclosure: I do not have the ability to build for osx so can't check)

    unless you are suggesting the "Utility.GetPlatformName()" is simply returning a blank.

    a print(Utility.GetPlatformName()); would not hurt on that line for debug purposes.

    Anyways, glad you got it kinda working. Are you saying it /does/ work now for you in a way that is helpful - or it doesn't? :)
     
    Last edited: Dec 29, 2015
    BackwoodsGaming likes this.
  2. memetic-arts

    memetic-arts

    Joined:
    Feb 27, 2011
    Posts:
    82
    Ah . . so actually the "OSX" shouldn't be included in the argument at all . . . what we ultimately want is: http://www.mysite.com/AssetBundles/OSX/

    Which, if the function were actually functioning, would mean all we'd have to pass is http://www.mysite/com/AssetBundles/ (with the trailing slash) as the absolute path, and the code would append "OSX" + "/" by virtue of Utility.GetPlatformName() + "/" . (And I realize this *is* what you had in your example, duly noted! :) )

    I'm going to try amending my code, but I'm pretty sure it's not going to make a difference (though those might very well be famous last words...)
     
    Last edited: Dec 29, 2015
    BackwoodsGaming likes this.
  3. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    Yes indeed, That method does indeed append the generated platform name :)

    Here is hoping!

    As you rightly mentioned, add the trailing slash AFTER AssetBundles.

    Or - Weld it into that method
    absolutePath+ "/" + Utility.GetPlatformName() + "/";

    However this will be re-broken upstream with the next update... so using the given convention is the path of least resistance :D
     
  4. memetic-arts

    memetic-arts

    Joined:
    Feb 27, 2011
    Posts:
    82
    Yes, can't really tell re: the above until the SetSourceAssetBundleURL function is fixed. All I know for sure is that when I set the variable "url" on line 311 to: http://www.mysite.com/AssetBundles/OSX/ , it works! For now, it's ok to be hardcoded, as I'm only releasing to one platform initially.

    I actually noticed that some work was done on this over in BitBucket, so maybe this is a known issue now . . . hoping again that someone from Unity will chime in here.

    Thanks again for the input @twobob, Happy New Year!
     
    twobob likes this.
  5. memetic-arts

    memetic-arts

    Joined:
    Feb 27, 2011
    Posts:
    82
    Ha! nice one!
     
    twobob likes this.
  6. memetic-arts

    memetic-arts

    Joined:
    Feb 27, 2011
    Posts:
    82
    Sorry, the tail-end of your post just now registered, and I realized I hadn't answered your questions. No, I'm not suggesting that; I'm suggesting that the entire value of BaseDownloadingURL is never transferred to m_BaseDownloadingURL for assignment to the variable "url" on line 311.

    I'm saying that I've found a less-than-optimal workaround and need some input from someone that understands the business in lines 64-69 in order to implement a proper fix.

    Cheers
     
    twobob likes this.
  7. TinyDev

    TinyDev

    Joined:
    Jul 9, 2013
    Posts:
    15
    For the most part we found the tutorial is put together well enough that we were up and running with the basic download of a bundle pretty quick.
    YMMV but we got this up and running in our project in less than an hour on a couple different Android devices and Windows all hitting an off-premise IIS server.
    We tested the Sim mode and local server first in the samples to make sure the scripts were working and then imported the package (sans samples) directly into our main project.
    We have not used variants in our project yet but it worked in the samples and seem pretty clear from the tutorial.
    Good samples, good tutorial and very valuable feature.
     
    twobob likes this.
  8. memetic-arts

    memetic-arts

    Joined:
    Feb 27, 2011
    Posts:
    82
    Glad to hear that it went so smoothly for you . . . were you importing entire scenes or individual assets? I'd be interested to know how you were able to import from a remote server without having to modify the AssetBundleManager.cs script.

    Cheers, Happy New Year!
     
    Last edited: Dec 31, 2015
  9. memetic-arts

    memetic-arts

    Joined:
    Feb 27, 2011
    Posts:
    82
    Since @TinyDev posted about how easy it was to implement, in light of the issues that I'd had, I decided to go back and re-investigate. Lo and behold, I solved it, though I'd still contend that the issue centered around a misplaced line of code int he LoadScenes.cs file. I provided the details in an EDIT to my ridiculously-long defect report above (post #52).

    Apologies again for sucking up so much page-space . . . but relieved that I finally got this working properly.
     
  10. TinyDev

    TinyDev

    Joined:
    Jul 9, 2013
    Posts:
    15
    Glad you got it working! The only thing we changed was to point the ABM to our server.

    _assetSource = "http://blahblahblah/"
    AssetBundleManager.SetSourceAssetBundleURL(_assetSource);

    For our first quick'n'dirty test, we did upload the demo assets (including the scene) to our server and tested individual assets and that scene.

    Since the first post we have successfully worked with variants - but we've created our own manager to address our needs.

    In retrospect the fact you are working with OSX vs Android and (IIRC) LAMP instead of IIS maybe created more headaches for you than we experienced...again YMMV :)
     
  11. memetic-arts

    memetic-arts

    Joined:
    Feb 27, 2011
    Posts:
    82
    @TinyDev, thanks for the info. For me, it wasn't so much that it was OSX, but that I was trying to get it to work properly within the Editor before deploying to any one platform. In the end it really was just the placement of that call to SetSourceAssetBundleURL() -- if you want it to run from the Editor, it has to go outside of that
    Code (csharp):
    1. #if Development Build || Editor
    statement.

    Cheers
     
  12. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,664
  13. Danzdiship

    Danzdiship

    Joined:
    Dec 29, 2015
    Posts:
    6
    Hello Everybody,
    I am new to unity and I used the assetbundle for storing 3D models on a FTP Filezilla Server which would be augmented on detection of a target image using vuforia. The augmentation is coming upon detection but can anyone tell me how can I be sure that the asset bundle is working or not(I mean that is the model being loaded from the local project folder or being downloaded and loaded from the server directly).
    Thank You.
     
  14. domkia

    domkia

    Joined:
    Aug 19, 2012
    Posts:
    99
    How do I get local manifest file? I want to compare old already downloaded with the new one in the server.
     
  15. TinyDev

    TinyDev

    Joined:
    Jul 9, 2013
    Posts:
    15
    Remove the assets from your project after you build the bundle - if you still get the model it sure won't have been loaded from the local project folder.
     
  16. TinyDev

    TinyDev

    Joined:
    Jul 9, 2013
    Posts:
    15
    Take a look in the "Contents of the “AssetBundles” folder, grouped by build target."
     
  17. Danzdiship

    Danzdiship

    Joined:
    Dec 29, 2015
    Posts:
    6
    Thank You for the early reply TinyDev. I just compressed one .fbx model and when I deleted it, the augmentation didn't come. This would mean there is some logical error in my code. I followed the documentation of AssetBundles and implemented 2 set of C# scripts, one is the AssetBundleExporter and the other is for downloading and loading the asset on detection. Here is the code for it, please help me fix the problem or guide me through it :

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System;
    4.  
    5. public class CachingLoadExample : MonoBehaviour {
    6.     public string BundleURL;
    7.     public string AssetName;
    8.     public int version;
    9.    
    10.     void Start() {
    11.         StartCoroutine (DownloadAsync());
    12.     }
    13.  
    14.  
    15. IEnumerator DownloadAsync () {
    16.     // Start a download of the given URL
    17.         WWW www = WWW.LoadFromCacheOrDownload ("170.25.245.XX", 1);
    18.    
    19.     // Wait for download to complete
    20.     yield return www;
    21.    
    22.     // Load and retrieve the AssetBundle
    23.     AssetBundle bundle = www.assetBundle;
    24.  
    25.     //Check if the assetBundle is actually downloaded or not
    26.  
    27.     if (bundle != null) {
    28.             // Load the object asynchronously
    29.             AssetBundleRequest request = bundle.LoadAssetAsync ("beanbag", typeof(GameObject));
    30.    
    31.             // Wait for completion
    32.             yield return request;
    33.    
    34.             // Get the reference to the loaded object
    35.             //GameObject obj = request.asset as GameObject;
    36.    
    37.             // Unload the AssetBundles compressed contents to conserve memory
    38.             bundle.Unload (false);
    39.         }
    40.    
    41.     // Frees the memory from the web stream
    42.     www.Dispose();
    43. }
    44.  
    45. }
     
    twobob likes this.
  18. BakuDigital

    BakuDigital

    Joined:
    May 9, 2013
    Posts:
    18
    Hey !

    Thanks for this assetbundle manager, the basics work well and it's easy to set-up, thanks to the well explained tutorial.

    However, If I can suggest two things:

    1. you should natively integrate a way to get the current download progress and explain it in the tutorial. It wasn't very difficult, but I think it's an essential feature for an AssetBundle Manager and it shouldn't require "investigation" to get it work.

    2. Also, LoadFromCacheOrDownload should allows us to use the application offline if some bundles have already been downloaded. It's curious that we can't work offline with this Manager... I think it's also an essential feature and it shouldn't require some tweaking (As I did not implemented it yet, I do not know if it's difficult...).

    Otherwise, everything works as expected, dependencies between scenes and assets from different bundles are well handled ! ;)

    Cheers.
     
    User340, Meic, ZeFirestarter and 2 others like this.
  19. memetic-arts

    memetic-arts

    Joined:
    Feb 27, 2011
    Posts:
    82
    @bloodbc, re: #2, you can work offline . . you need to be in either Simulation Mode or Local AssetBundle Server mode . . . accessed via the menu Assets>AssetBundles>

    Explanation of usage is in the first section of the tutorial.
     
  20. memetic-arts

    memetic-arts

    Joined:
    Feb 27, 2011
    Posts:
    82
    I was wondering if anyone has tried to add a block to AssetBundleManager.cs for AssetBundles.LoadAllAssets, as right now it only handles loading one asset at a time (and I don't want to load an entire scene for the task at hand). I was going to give a try, but if some kind soul out there has already done it, I'd rather not burn cycles.

    Thanks!
     
  21. Danzdiship

    Danzdiship

    Joined:
    Dec 29, 2015
    Posts:
    6
    Hello Everybody,
    I am new to Unity and I am trying to develop an AR App using Vuforia. I am using AssetBundles in my project. Below is the Code I have implemented, but I am getting the following error:
    UnityException: WWW Download had an error: Couldn't open file /C:/Users/danish.aziz/Desktop/test/AssetBundles/bean-chair.unity3d
    AssetBundleAugmenter+<DownloadAndCache>c__Iterator0.MoveNext () (at Assets/Vuforia/Scripts/AssetBundleAugmenter.cs:30)


    And also as the Build.Pipeline is obsolete now, how do I build my asset bundles for specific target?
    Please Help me out, I have tried everything I could and now I am stuck.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System;
    4. using Vuforia;
    5.  
    6. public class AssetBundleAugmenter : MonoBehaviour, ITrackableEventHandler {
    7.     public string AssetName;
    8.     public int Version;
    9.     private GameObject mBundleInstance = null;
    10.     private TrackableBehaviour mTrackableBehaviour;
    11.     private bool mAttached = false;
    12.     void Start() {
    13.         StartCoroutine(DownloadAndCache());
    14.         mTrackableBehaviour = GetComponent<TrackableBehaviour>();
    15.         if (mTrackableBehaviour) {
    16.             mTrackableBehaviour.RegisterTrackableEventHandler(this);
    17.         }
    18.     }
    19.     // Update is called once per frame
    20.     IEnumerator DownloadAndCache() {
    21.         while(!Caching.ready)
    22.             yield return null;
    23.         string bundleURL = "file:///C:/Users/da/Desktop/test/AssetBundles/bean-chair.unity3d";
    24.         WWW www = WWW .LoadFromCacheOrDownload (bundleURL, 0);
    25.             yield return www;
    26.             if (www .error != null)
    27.                 throw new UnityException("WWW Download had an error: " + www .error);
    28.             AssetBundle bundle = www .assetBundle;
    29.             if (AssetName == "") {
    30.                 mBundleInstance = Instantiate (bundle.mainAsset) as GameObject;
    31.             }
    32.             else {
    33.                 mBundleInstance = Instantiate(bundle.LoadAsset ("Chair_03")) as GameObject;
    34.             }
    35.  
    36.     }
    37.     public void OnTrackableStateChanged(
    38.         TrackableBehaviour.Status previousStatus,
    39.         TrackableBehaviour.Status newStatus) {
    40.         if (newStatus == TrackableBehaviour.Status.DETECTED ||
    41.             newStatus == TrackableBehaviour.Status.TRACKED ||
    42.             newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED) {
    43.             if (!mAttached && mBundleInstance) {
    44.                 // if bundle has been loaded, let's attach it to this trackable
    45.                 mBundleInstance.transform.parent = this.transform;
    46.                 mBundleInstance.transform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
    47.                 mBundleInstance.transform.localPosition = new Vector3(0.0f, 0.15f, 0.0f);
    48.                 mBundleInstance.transform.gameObject.SetActive(true);
    49.                 mAttached = true;
    50.             }
    51.         }
    52.     }
    53. }
     
  22. BakuDigital

    BakuDigital

    Joined:
    May 9, 2013
    Posts:
    18
    @memetic arts
    I'm aware, that's true for the editor (Or it'll be a nightmare to test ^^). I was speaking on mobile after build: If you download the assets on the first launch, everything works fine. If you restart the application, still online, the assets are loaded from the phone memory (Or it'll be a total user-killer if we have to download the assets each start). However, if you restart the application and the phone can't reach the assetbundle server, it'll throw an error and the assets will not be loaded, even if they have been previously downloaded and stored on the phone.

    Maybe it's just me ? But after reading this thread, It looks like not.

    Update: Only the manifest assetbundle cannot be loaded from cache. I quote a comment in AssetBundleManager.cs:

    //For manifest assetbundle, always download it as we don't have hash for it.
    So a workaround was to store it manually to a place where i can load him via a local url (persistentDataPath). Then only require check for a new manifest assetbundle on server when i upgrade the version number, since i don't plane to change the asset bundles for a same version. Assetbundle files management stays the same with LoadFromCacheOrDownload().

    As for your LoadAllAssets, you can load only one prefab where the assets you want are referenced or objects you want are childs ? Since AssetBundle Manager handles dependencies...

    Cheers
     
    Last edited: Jan 15, 2016
  23. memetic-arts

    memetic-arts

    Joined:
    Feb 27, 2011
    Posts:
    82
    Ah, ok . . . what you wrote didn't mention building to the phone at all. I guess I didn't think of that way because my app requires GPS, so is pretty much useless without a connection. :)

    Right, that's the current state . . . I was asking if anyone had perhaps extended it to support the LoadAllAssets method. Though for what I need, which is to pull down a set of unreferenced textures, it's probably best to use AssetDatabase.LoadAllAssetsAtPath, and was hoping to integrate within the AssetBundle Manager framework rather than create a one-off script.

    I'm in the midst of trying to get that to work...
     
  24. memetic-arts

    memetic-arts

    Joined:
    Feb 27, 2011
    Posts:
    82
    Greetings -

    Would someone out there happen to know where exactly in the AssetBundle Manager file-set that a given assetbundle is actually unloaded? I can see the group of functions for unloading assets and their dependencies, but I can't find where the main function -- unloadAssetBundle - is actually called/executed.

    I've started getting the "can't be loaded because another AssetBundle with the same files is already loaded" error, and have not been able to find the proper place to insert the "bundle.Unload(false)" statement. I can see it included already in unloadAssetBundle(), but, as I said, that function never seems to get called from anywhere.

    Thanks in advance.
     
    Last edited: Jan 18, 2016
  25. Danzdiship

    Danzdiship

    Joined:
    Dec 29, 2015
    Posts:
    6
    Can somebody please help me with my previous question. Any kind of help will be very supportive of you'll for a newbie.
    Thank You.
     
  26. jakovd

    jakovd

    Joined:
    Mar 9, 2010
    Posts:
    15
    I need help to understand how asset bundles would be constructed for the project I am currently working on.
    The project loads many scenes. The idea is to build asset bundles packed with everything we have on specific scene but - one asset can be used in more than one scenes so it needs to be included (or referenced) in all those asset bundles.
    I am creating asset bundle maps (AssetBundleBuild) from code, since assigning asset bundles in editor would be too much manual work for the amount of content we have.
    Let me use this simplified example of asset bundle hierarchy that I would like to achieve:

    scene1_asset_bundle
    - shared_asset
    - other_assets
    scene2_asset_bunde
    - shared_asset
    - other_assets2

    If I pass the AssetBundleBuild specifications for scene1 and scene2 as displayed to BuildPipeline.BuildAssetBundles method I get the error that shared_asset has been marked into more than one AssetBundle.
    So the idea is that I need to build an asset bundle for shared_asset and reference that in scene bundles, right?

    shared_asset_bundle
    - shared_asset

    But how do I change the scene1_asset_bundle and scene2_asset_bundle
    reference that new asset bundle?

    I build shared_asset_bundle with BuildPipeline.BuildAssetBundles by providing only one AssetBundleBuild (map with single asset).

    But how do I specify that it needs to be referenced in scene asset bundles too?
     
  27. NRB007

    NRB007

    Joined:
    Jan 31, 2016
    Posts:
    3
    I want Basic Tutorial of asset Bundle By Will Goldsten Sir!!!
     
    SimonDarksideJ likes this.
  28. Ali_V_Quest

    Ali_V_Quest

    Joined:
    Aug 2, 2015
    Posts:
    138
    if you are talking about the live training session,, it's not available on the unity learn site, check it out here
    http://takhtesefid.org/watch?v=956854320328
     
    domkia likes this.
  29. Ali_V_Quest

    Ali_V_Quest

    Joined:
    Aug 2, 2015
    Posts:
    138
    can you include asset bundles in the build ?
    - we want to simply support sd & hd using asset bundle variantes,
    - however, we don't want to maintain servers.
     
  30. BakuDigital

    BakuDigital

    Joined:
    May 9, 2013
    Posts:
    18
    Yes. Put them in the StreamingAssets folder ;) then use:
    Code (CSharp):
    1. AssetBundleManager.SetSourceAssetBundleURL(Application.streamingAssetsPath + "/");
     
    eDmitriy and Ali_V_Quest like this.
  31. Ali_V_Quest

    Ali_V_Quest

    Joined:
    Aug 2, 2015
    Posts:
    138
    Thanks for that, helped very much
     
    twobob likes this.
  32. pain_gwar

    pain_gwar

    Joined:
    Apr 14, 2013
    Posts:
    22
    Try to load assets bundle variants from a local iOS build and didn't work.

    Don't know why, always have error about URL.

    I have done what @bloodbc said, i can see my asset bundles file in Xcode project under "Data/Raw" directory and even the URL is correct, but still have error.

    Any idea ?
     
  33. BakuDigital

    BakuDigital

    Joined:
    May 9, 2013
    Posts:
    18
    What kind of error ? try this on iOS :

    Code (CSharp):
    1. AssetBundleManager.SetSourceAssetBundleURL("file://" + Application.streamingAssetsPath + "/");
     
  34. kukuta

    kukuta

    Joined:
    Feb 12, 2016
    Posts:
    1
    I think it could be the best one, if it covers download progress.
    I need some information for how many files dose it have to dowonload, how many bytes has been downloaded...
    Is there no plan to add above??
     
  35. pete

    pete

    Joined:
    Jul 21, 2005
    Posts:
    1,647
    I got excited when I saw a scene loading demo but dang, it's just a cube, a plane and a texture. What about objects with scripts on them? In scene objects that are connected to scripts in the inspector? The only solution for that is reflection and then rebuilding the connections - right? I'm trying to come up with a solution for level streaming in WebGL but it's looking like we're out of luck. We have so many UI panels controlled through script in our project. I don't see the reflection route being manageable for us. Or am I misunderstanding something?
     
  36. thienhaflash

    thienhaflash

    Joined:
    Jun 16, 2012
    Posts:
    513
    I was trying to use the new asset bundles system in my company's project. I see that beside the assetbundles generated, Unity generate 2 more per-platform files.

    The problem is we have many asset bundle projects and those 2 files always got overwritten by the last project's exportation. We have like 20 asset bundle projects because the assets are very heavy to put everything inside 1 project.

    Are there anyway to make those 10 asset bundle projects work so that I can load any asset in any project at run time when I need ?

    Thanks.
     
  37. memetic-arts

    memetic-arts

    Joined:
    Feb 27, 2011
    Posts:
    82
    Greetings -

    The AssetBundle Manager sample project demonstrates loading one scene. Does anyone have an example of how to properly do scene-switching via AssetBundles? It's easy enough to use LoadLevel when levels/scenes are included in the build, but I'm having some issues achieving this with AssetBundles.

    Basically, I have a core scene which functions as the GUI Menuing system from which Levels are selected. And loading the initial scene from the menu works 100% as expected. However, upon re-accessing the menu and making another selection, the next scene loads, but without its own textures -- only the old materials from the previous scene are applied.

    I've tried various approaches with Destroy() -- which does visibly remove objects from the hierarchy -- but then upon unloading the fist scene and loading the second, the Material Renderer on the object shows the texture from the first!

    Also worth noting: in the simple two-scene experiment that I've been working with, it doesn't matter which scene I load first -- the first one always loads as expected, and the second loads without its own textures as described above.

    As with other obstacles / questions I've posted, I'm sure I'll figure this out eventually, but would really appreciate input so I don't have to spend another week figuring this out.

    Thank you!!
     
    Last edited: Feb 16, 2016
  38. memetic-arts

    memetic-arts

    Joined:
    Feb 27, 2011
    Posts:
    82
    bumping this. Have been researching / experimenting like madman, no success. Anybody have a clue how to effectively switch scenes via Assetbundles - using the AB Manager system or otherwise?
     
  39. pain_gwar

    pain_gwar

    Joined:
    Apr 14, 2013
    Posts:
    22
    @bloodbc That works, thanks! Think i was missing the "file://" part.

    Thanks again for the help!
     
  40. adamt

    adamt

    Joined:
    Apr 1, 2014
    Posts:
    116
    Sorry if this has already been addressed, but I feel like I have a pretty simple use case for Asset Bundles, and I'm not sure Asset Bundle Manager helps me more than using the low-level API. Maybe I'm just missing something...

    We have a mobile game on iOS and Android. We want to bundle basic assets with the game, keeping it under 100 MB when submitted to the respective app stores. The first time a player opens the game, he will see a loading screen with a progress bar that will download every remaining asset not included with the base executable from the app store (it'd be a bit more user-friendly in that we'd ship with the first area of the game bundled with the game, and the remaining assets would download in the background while you explore the first area).

    I looked into Asset Bundles as a solution to this because the manifest seems to handle asset versioning automatically, in case we change an asset after launch or add one to an existing bundle. However, it seems like Asset Bundle Manager is more concerned with the lazy loading and instantiating of scenes and assets at runtime, which is a bit too clever in my opinion. We're not streaming assets in an open world, nor are we concerned with removing downloaded assets when they're no longer needed (in our case, they'll always need to be available on the device). We simply want to make sure the entirety of our game -- including any new content since the player last opened it -- has been downloaded before the player is able to continue playing.

    Is this something the low-level API would be better suited to? If not, I'd love to know how you'd suggest I craft my use of Asset Bundle Manager to support this. If the low-level API route is the way to go, I've got a couple questions:
    1. Once I've downloaded an Asset Bundle onto my iOS/Android device through WWW.LoadFromCacheOrDownload() and have an instance of the Asset Bundle through the WWW instance's assetBundle property, it seems like AssetBundle#LoadAllAssets() can be used to access the contained assets. At that point, are those assets stored on my device's filesystem, available to something like Resources.Load(), or is the Asset Bundle the only thing stored, and is the act of loading an asset simply loading it from the Asset Bundle into memory (i.e., is it something I need to do every time the game is opened)?
    2. Should I call AssetBundle#Unload(false) on the Asset Bundle once all of its contained assets have been loaded? It seems like this would depend on the answer to #1, since if the assets don't actually get stored on the filesystem during AssetBundle#LoadAllAssets(), I'd still need to have the downloaded Asset Bundle to load the assets back into memory when the game is re-opened.
    As an aside, I'd love to have overall better documentation around Asset Bundles. It seems like information is kind of all over the place (forums, tutorials, and the official documentation). I've also noticed that Asset Bundle Manager is using an undocumented overload for the WWW.LoadFromCacheOrDownload() function that passes a Hash128 instance instead of an int for the Asset Bundle's version. I'd love to have actual parity between functions in the API and the documentation, to avoid headaches (it also makes me wonder if the version of the function you're using is deprecated, or if the one on the documentation is, or what).
     
    twobob, MatLoz and davidosullivan like this.
  41. davidosullivan

    davidosullivan

    Joined:
    Jun 9, 2015
    Posts:
    387
    I have been wondering the same thing as @adamt i.e. I have been trying to find a way to make AssetBundleManager just load an asset bundle and its dependencies, but there does not seem to be an AssetBundleManager.LoadAssetBundle method- its all conerned with loading levels and assets. But what if I know that my game at some point needs to load an assetbundle and its dependencies, rather than a level and its dependencies or an asset and its dependencies. i.e. I use UMA so what if I want a character customization scene to download all the characters the user could use. What I'd like to do is say AssetManager.LoadAssetBundle(someRace) and have AssetManager also do its magic on all the bundles someRace depends on, but there does not seem to be a way of making AssetManager just load an assetbundle and its dependencies.

    It may well be that I am just hopelessly confused here (which I am) and that I should just be using Unity native stuff for this, but does that include dependencies etc? If it does whats the point of AssetBundleManager and its manifests?
     
  42. davidosullivan

    davidosullivan

    Joined:
    Jun 9, 2015
    Posts:
    387
    For me my situation is this:
    UserA plays the game and customizes it. When they customize it additional AssetBundles they choose to use get downloaded dynamically.
    UserA then sends their customization of the game to User B.
    When UserB plays the game the game needs to PRE download any asset bundles that are necessary in order to play UserA's customized version.
    User B then plays UserA's customized version but might then customize it themselves and send it to UserC
    and so on...
     
  43. davidosullivan

    davidosullivan

    Joined:
    Jun 9, 2015
    Posts:
    387
    So AssetBundleManager seems to be helpful when UserA downloads stuff dynamically, but how do I get a list of what UserA used, so that when UserB loads the game, everything UserA used gets downloaded before UserB's game starts?
     
  44. tswalk

    tswalk

    Joined:
    Jul 27, 2013
    Posts:
    1,109
    seems like you'll need to inject some type of guid management into your bundles that can be 'communicated' between the clients... allowing each to recognize the others asset availability.
     
  45. davidosullivan

    davidosullivan

    Joined:
    Jun 9, 2015
    Posts:
    387
    I think what I am finding confusing is understanding which parts of the workflow and methods are part of Unity, and which parts are part of the specific workflow that ABM adds to the standard Unity workflow. For example when you build your asset bundles and you and up with a 'Windows' folder, with a 'Windows' thing and a 'Windows.manifest' thing inside, is this what Unity would have made natively or is this something specific to ABM?

    And since the data in the manifest seems to be so crucial, I am confused why it cannot be accessed by a script that uses ABM... without changing the property to the following you cannot get the manifest object that asset bundle manager is using...
    Code (CSharp):
    1. public static AssetBundleManifest AssetBundleManifestObject
    2.         {
    3.             get { return m_AssetBundleManifest; }//add this line so scripts can also use the manifest.
    4.             set {m_AssetBundleManifest = value; }
    5.         }
     
  46. edl7878

    edl7878

    Joined:
    Mar 22, 2016
    Posts:
    1
    Hi,
    I am testing assetbundle manager for several days, and look through the code many times.

    I noticed that assetbundle manager maintain several static map or list:

    static Dictionary<string, LoadedAssetBundle> m_LoadedAssetBundles = new Dictionary<string, LoadedAssetBundle> ();
    static Dictionary<string, WWW> m_DownloadingWWWs = new Dictionary<string, WWW> ();
    static Dictionary<string, string> m_DownloadingErrors = new Dictionary<string, string> ();
    static List<AssetBundleLoadOperation> m_InProgressOperations = new List<AssetBundleLoadOperation> ();
    static Dictionary<string, string[]> m_Dependencies = new Dictionary<string, string[]> ();
    static string m_BaseDownloadingURL = "";
    static string[] m_ActiveVariants = { };

    after set the right url, and manager will get the "webplayer" assetbundle to retrive dependence between bundles, and user can load different objs from manager.

    since the basic info is stored static, no matter how many bundlemanager obj is created, all of them just use the same info, and I am wondering, does the bundlemanager just support download from one place, after AssetBundleManager.Initialize() is called.

    let's say there is a very big construction model library, to load all of the library's model in unity3d is impossible. So the developers divided them into 3 parts in three unity3d projects, and output them with assetbundle manager, and published them in three folders of web server, each folder correspond to one project's assetbundle manager output. and the three folder is fa,fb and fc.

    what I want to ask:

    1 after AssetBundleManager.Initialize() with fa, and do some loading thing, if I use AssetBundleManager.Initialize() to reinitialize manager to fb, CAN bundlemanager work correctly?

    2 I think it is not possible to access fa, fb, fc at the sametime with one bundlemanager, AM I right?

    3 if modify code without using static, is it possible to implement bundlemanager, that could be instanced several times, and access fa, fb and fc at the sametime?

    I am eager to hear any responds, thank you very much.
     
  47. User340

    User340

    Joined:
    Feb 28, 2007
    Posts:
    3,001
    Who can I contact for Asset Bundle Manager support? Is there an email or something?
    I need to clarify the following points:

    1) If the AssetBundle has already been cached, why do you still need internet? How can I access the cached bundle? I would like my app to function offline if the download has already taken place.

    2) How can I check if the bundle has already been cached?
     
  48. Kiupe

    Kiupe

    Joined:
    Feb 1, 2013
    Posts:
    528
    Hi,

    I have one question about Asset Bundles Variants and App Slicing. The AssetBundleManager scene variant demo illustrates how to have an SD and HD version of a scene - that's great. What I want to know is, will it work with Sprites with a packing tag and how ? I have two concerns with that :

    - will the atlas generated by the Sprite Packer included in the asset bundle variant ?
    - The SD and HD version must have the same structure, but Sprites must have a different packing tag in order to have 2 different atlases, one HD and one SD - so atlases won't have the same name, will it be a problem ?

    Thanks
     
    MatLoz likes this.
  49. eDmitriy

    eDmitriy

    Joined:
    Aug 22, 2013
    Posts:
    13
    Hi. If you need to know bundle download progress look at this line in AssetBundleManager class
    Code (CSharp):
    1. public static Dictionary<string, WWW> m_DownloadingWWWs = new Dictionary<string, WWW> ();
    2.  
    I just made it public static. Using in LoadAssets example
    Code (CSharp):
    1. WWW currWWW = AssetBundleManager.m_DownloadingWWWs[AssetBundleManager.m_DownloadingWWWs.Keys.ToArray()[0]];
    2. .....
    3. downloadProgressTemp = currWWW.progress * 100f;
    4.  


    A lot of peoples asking how to work with AssetBundleManager in offline. I used WWW.LoadFromCacheOrDownload(url, version, 0) for manifest file and for bundle.
    For me it works offline and download updates if they exists.
    You need to read version info from your hosting, in my case it's a simple .txt with names of the bundles and their versions. Every time you download and cache bundle you pass version and it saves with bundle in cache. After update of your bundle on hosting increase version in your hosted versions file. If you pass version that used in your cache manager will download from cache, if version is larger it will download from url.
    My versions file:
    Android 9
    tile_1111_cubesnight 9
    tiles_bundle_01 9
    --

    Every time versions will downloaded it going to be saved in PlayerPrefs, when game is offline it will read version info from saved data.
    For my purposes I modified only Assets Download but Scene load work similar. So look at this function at AssetBundleManager
    293 static protected bool LoadAssetBundleInternal (string assetBundleName, bool isLoadingAssetBundleManifest)
    ......
    Code (CSharp):
    1.  
    2.         static protected bool LoadAssetBundleInternal (string assetBundleName, bool isLoadingAssetBundleManifest)
    3.         {
    4.             // Already loaded.
    5.             LoadedAssetBundle bundle = null;
    6.             m_LoadedAssetBundles.TryGetValue(assetBundleName, out bundle);
    7.             if (bundle != null)
    8.             {
    9.                 bundle.m_ReferencedCount++;
    10.                 return true;
    11.             }
    12.    
    13.             // @TODO: Do we need to consider the referenced count of WWWs?
    14.             // In the demo, we never have duplicate WWWs as we wait LoadAssetAsync()/LoadLevelAsync() to be finished before calling another LoadAssetAsync()/LoadLevelAsync().
    15.             // But in the real case, users can call LoadAssetAsync()/LoadLevelAsync() several times then wait them to be finished which might have duplicate WWWs.
    16.             if (m_DownloadingWWWs.ContainsKey(assetBundleName) )
    17.                 return true;
    18.    
    19.             WWW download = null;
    20.             string url = m_BaseDownloadingURL + assetBundleName;
    21. //!!!!!!!!!        
    22.             // For manifest assetbundle, always download it as we don't have hash for it.
    23. /*           if (isLoadingAssetBundleManifest)
    24.            {
    25.                 download = new WWW(url);//THIS LINE PREVENTS OFFLINE WORK
    26.            }
    27.            else
    28.            {
    29.                 download = WWW.LoadFromCacheOrDownload(url, m_AssetBundleManifest.GetAssetBundleHash(assetBundleName), 0);
    30.            }*/
    31.  
    32.            string txt = LoadAssets.bundlesVersionsFromServer;
    33.            int startN = txt.IndexOf(assetBundleName);
    34.            int lastN = txt.IndexOf("\n", startN);
    35.            txt = txt.Substring(startN, lastN - startN);
    36.            startN = int.Parse(txt.Split(' ')[1]);
    37.  
    38.            download = WWW.LoadFromCacheOrDownload(url, startN, 0);
    39. //!!!!!!!!!!!!    
    40.             m_DownloadingWWWs.Add(assetBundleName, download);
    41.    
    42.             return false;
    43.         }
    44.  
    not so elegant but it works)

    Hope this will be helpful. And sorry for my english)
     
    moonabook, twobob and BakuDigital like this.
  50. davidosullivan

    davidosullivan

    Joined:
    Jun 9, 2015
    Posts:
    387
    Is there any way I can start the LocalAssetBundleServer from another script? Its just I have some people testing a package I have made that uses it and literally all of them are having issues because they dont have the local server turned on. I know I can try to make the fact that they need to turn it on in the instructions, flash reed or something, but it would be nicer if I could just make it work for them and just start the server when the game runs...
    I'm trying this, but sometimes it works and some times it doesn't
    Code (CSharp):
    1. if (!Menu.GetChecked("Assets/AssetBundles/Local AssetBundle Server"))
    2.                 {
    3.                     Debug.Log("Local AssetBundle Server was not on");
    4.                     EditorApplication.ExecuteMenuItem("Assets/AssetBundles/Local AssetBundle Server");
    5.                     Menu.SetChecked("Assets/AssetBundles/Local AssetBundle Server", true);
    6.                 }