Updating content without download all AssetBundle?

Hi all!

It’s my first time working with AssetBundles and I have a lot of question. I’m building and app that download the content from Amazon AWS. The problem is that the Assetbundle has 4 GB size (it’s a video app) and I don’t want to download all assetbundle every time I fix/updated part of the scripts or videos.

I read a lot of post, videos, documentation but I don’t know how to get this… Can I do with addressables? Or with UnityWebRequest/WWW.loadFromCacheOrDownload ?

Pretty sure both AssetBundles and Addressibles are predicated on downloading the entire chunk before you get at it. I know ABs are that way, but I haven’t used Addressibles.

Another approach is to break it into multiple bundles and only download the one(s) you need.

If you are just looking for streaming some video, I think Unity can do that with one of its APIs, but I haven’t played around with anything like that in years and years, and I know it has all changed since. Google will be your friend here.

1 Like

Thanks for response!

I have the code to streaming video but the problem is that the videos are for VR and need a lot of bit rate/download connection to stream the video.
The original idea was that create an asset bundle and download 1 time, and when the bundle has an update, only download the part of the bundle.
In Oculus store for VR heatset, when you upload the updated bundle, the user only download the part’s that changed. For example, if you change a some scripts, the user download only 2 MB of scripts and not the 4 GB of the asset bundle.

It’s my first time working like this with asset bundles, and I don’t know how to start to engage with this, and I don’t know if unity can do this.

For now, I divided the app in 2 parts, apk with scenes and scripts and second with diferents assetbundles for every video. I see that you can build a assetbundle for streaming video, anyone has any idea how works this type of bundle?

If you change a part of the video, you have to re-download the whole video.
AFAIK you cannot update a specific segment of a bundle’s binary data.

If you have another small asset that is in the same bundle as the video, simply split the bundle into multiple bundles and load it as a dependency. That way you can update the smaller bundles while the larger bundles stay mostly the same. Addressables does this dependency downloading for you. All you have to do is split the assets into different groups.

If you change scripts you have to build the apk and upload it to the oculus store as well. The apk gets re-downloaded as a whole and not just a part of it. So if your apk is 50 mb, it’ll download that 50 mb everytime you update. I’m not sure how that works with Oculus’ expansion assets. Also you cannot update scripts through asset bundles.

Asset Bundle management is quite tedious and can get complicated easily. Addressables does a lot for you, so if you’re starting with Asset Bundles, I’d suggest looking into Addressables instead.

In our own project we simply download video files directly from the content server. Then stream them from disk.
When video’s are updated, the video gets re-downloaded.
In our case streaming them from the server directly gave some buffering issues which prevented it from playing back smoothly. Downloading and Streaming from disk solved that. It takes longer to show the video but at least it gives a smoother playback.

With addressables I can download the content (videos in this case) with some loading bar that the user can see and save in cache or streamAssets for Android/IOS?

Addressables does the caching for you.
Where you build them to is up to you and the asset group setting.
If you want specific assets to live in the StreamingAssets folder simply create that setting and set it on the group.

As for a loading bar when you load an asset you get an AsyncOperationHandle which has a progress property PercentComplete.
Simply request the asset and track its progress.

Try it in a simple prototype, I’d say.

https://docs.unity3d.com/Packages/com.unity.addressables@1.11/manual/AddressableAssetsGettingStarted.html

Thank you, I will test!

Another question, If I want update a video content (modify video of the asset) from assetbundle, how do this with addressables this update? How detect if the bundle are diferent? Any version number control of the bundle?

I’m reading this that how works addressables

https://docs.unity3d.com/Packages/com.unity.addressables@0.6/manual/AddressableAssetsDevelopmentCycle.html

Addressables handles most of that for you. Build the bundles again, upload to the content server.
A new content build will produce a new catalog. I haven’t updated content multiple times at runtime yet but it is possible.

Read:
https://docs.unity3d.com/Packages/com.unity.addressables@1.11/manual/AddressableAssetsDevelopmentCycle.html#building-for-content-updates

Thanks! I will test and share my experience when I test this. Thanks a lot!

I’m having some problems with addressables. Using this code:

public List<AssetReference> referenceBundlesVideos = new List<AssetReference>();

Addressables.LoadAssetAsync<AssetBundle>(referenceBundlesVideos[0]).Completed += bundleLoaded;

    void bundleLoaded(AsyncOperationHandle<AssetBundle> assetObj)
    {
        AssetBundle temporal = assetObj.Result;
    }

Unity return me that error:

Exception encountered in operation UnityEngine.ResourceManagement.ResourceManager+CompletedOperation1[UnityEngine.AssetBundle], result='', status='Failed': Exception of type 'UnityEngine.AddressableAssets.InvalidKeyException' was thrown., Key=b098d66ca73126848b071c4cf33f867f, Type=UnityEngine.AssetBundle* *UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase1:<.ctor>b__33_0(AsyncOperationHandle)
DelegateList1:Invoke(AsyncOperationHandle) (at Library/PackageCache/com.unity.addressables@1.8.4/Runtime/ResourceManager/Util/DelegateList.cs:69)* *UnityEngine.AddressableAssets.Initialization.<>c__DisplayClass14_0:<LoadContentCatalogInternal>b__0(AsyncOperationHandle1)
DelegateList1:Invoke(AsyncOperationHandle1) (at Library/PackageCache/com.unity.addressables@1.8.4/Runtime/ResourceManager/Util/DelegateList.cs:69)
UnityEngine.ResourceManagement.ChainOperation2:OnWrappedCompleted(AsyncOperationHandle1)
DelegateList1:Invoke(AsyncOperationHandle1) (at Library/PackageCache/com.unity.addressables@1.8.4/Runtime/ResourceManager/Util/DelegateList.cs:69)
UnityEngine.ResourceManagement.ResourceManager:Update(Single)
MonoBehaviourCallbackHooks:Update() (at Library/PackageCache/com.unity.addressables@1.8.4/Runtime/ResourceManager/Util/MonoBehaviourCallbackHooks.cs:19)

In the inspector I put the reference of addressable of the assetbundle or a direct mp4 video. If I put a gameobject, this code work perfect. Any idea?

I see that the problem is this line

Addressables.LoadAssetAsync<AssetBundle>(referenceBundlesVideos[0]).Completed += bundleLoaded;

The referenced assetbundle file it’s not an , it’s another type and when the Addressables intent to access and declare the type, comes the error. How I can declare the assetbundle file in the declaration?

I understand how Addressables works. No need to build a assetbundle, you can do this with addressables, that generates all the files needed to use in local or to upload in a hosting.
I have few questions now:

  • When I use “Addressables.DownloadDependencies(assetAddress);” every time the app read this line will be download the assets? Or with this command checks the asset package (json) in the hosting and if it has the same buildversion don’t download it?
  • If I have the first scene that download the asset and when finish the download I change to another scene, teorically I can access to the assets with the addressables.loadAsync, no? Or I need to load first in the first scene?
  • There’s any form to check first if there’s any updated package? I want to decide if the user want to download the package or use the old package in local.
  • If I have 4 catalogs and I hit the build button, will the 4 catalogs be built separately in different assets packages?