1

In my project, I have a bunch of items stored as assetBundles. In my server, I stored a list of item including their id and version. So ideally, using UnityWebRequest.GetAssetBundle(uri, versionId)I just get the item lists every time I open the app, if first opened, it will download every item; if secondly open, it will only download the one I have updated the version number on the server. Everything is very easy.

But now, I want to store those assetBundles at local first so that people don't need to download with cellular data.Is there an easy way to manage those assetBundles?

weijia_yu
  • 965
  • 4
  • 14
  • 31

2 Answers2

3

You can place the AssetBundles in the StreamingAssets folder. This is what the folder should look like:

Assets/StreamingAssets/

When you build the project, Unity will include the AssetBundles in the build. Of-course, you can use the Resources API but the StreamingAssets folder seems to be more appropriate here.

Once you place the AssetBundles there, you can use Application.streamingAssetsPath and AssetBundle.LoadFromFile to load the AssetBundle.

You can also use the WWW API with Application.streamingAssetsPath to load the AssetBundle.

Programmer
  • 121,791
  • 22
  • 236
  • 328
  • So I assume I need a local file to track my initial item id and version right? And if my item on server has newer version, I delete my old assetBundle and load from web. But how to implement that tracking system? If it is a text file, people will easily modify that and it will be a problem. – weijia_yu Jul 06 '17 at 00:49
  • Usually, you include the **minimum** objects that are required to play to the in the AssetBundles and package it with the game like I described above. It *cannot** be deleted. That's why I call it minimum. Now, as for the updates or extension packs that includes new Objects, download this to `Application.persistentDataPath/yourfolder/`. It will work on any platform. The Asset you downloaded and saved to `Application.persistentDataPath/yourfolder/` is the one you can download or update. You can create a simple data structure you can use to keep the version. – Programmer Jul 06 '17 at 01:51
  • [This](https://stackoverflow.com/a/40966346/3785314) post I made has a function to simple save/load/delete that data from `Application.persistentDataPath`. As for people being able to modify a file, you **cant** stop that. You really can't if it's running on their device. Just add basic encrypt/decrypt function to save your files but they can still be hacked regardless. – Programmer Jul 06 '17 at 01:55
  • Because I will probably update the assetBundle later, I can choose download newer version without deleting existing local one. But I think since I don't need old one anymore, I can just delete the old one? – weijia_yu Jul 06 '17 at 02:54
  • `Application.streamingAssetsPath` is read only. You can't delete anything from it. It's like a computer with a backup BIOS that you can't update/delete. If you want to delete old AssetBundle then you have to use `Application.persistentDataPath`. This means that you will not ship the game with the Assetbudle. You have to make the user download the Assetbudle during run-time and it to `Application.persistentDataPath`. You can then delete be able to delete or update it. – Programmer Jul 06 '17 at 03:04
  • Thanks, I guess I will just leave the assetBundle there, it is not too big – weijia_yu Jul 06 '17 at 03:25
  • Leave it where? StreamingAssets? – Programmer Jul 06 '17 at 03:30
  • Yes, when I detect the version is newer, i just use GetAssetBundle from web instead of local one. – weijia_yu Jul 06 '17 at 03:32
  • Good. That's what I would do too since I want my game to be playable right away after it's downloaded. One trick to note is that if your game have levels, separate your AssetBundles into levels then only include level 1 to 2 to the StreamingAssets. Since the other levels are not unlocked, they won't need to be played. You can then download one level after another when they finish previous levels. This is what most companies do. – Programmer Jul 06 '17 at 03:40
  • 1
    Thanks for the tip! – weijia_yu Jul 06 '17 at 03:41
  • @Programmer but with this approach, we won't be able to patch Level1/Level2 asset bundles later on, unless we load with LoadFromCacheOrDownload or with some other storage/caching solution - but this will be a waste of memory (Level1+Level2 assetbundles will take memory under the StreamingAssets + the caching solution). Any other way to tackle this? Without memory duplication and with the ability patch the stored asset bundles? – Tomer Peled Oct 05 '17 at 20:32
  • @TomerPeled Please read my comments under this answer. You **can't**. StreamingAssets is read-only and the doc makes that clear. The only way to be able to update it at-all is to not include the AssetBundles in the build. Simply download it from your server and save to `Application.persistentDataPath`. You can then be able to delete and download newer version but its downside is that the game is not complete until the AssetBundle is downloaded. – Programmer Oct 05 '17 at 20:41
  • @Programmer Not exactly - see over here: https://unity3d.com/learn/tutorials/temas/best-practices/assetbundle-usage-patterns#Cache_Priming But the limitation as I understand it that we'll have duplication of Level1+Leve2 in this approach. – Tomer Peled Oct 05 '17 at 20:46
  • @TomerPeled I just explained what to do to update AssetBundle and not get a duplicate which is a waste of memory and space but you replied with "Not Exactly" and with a link. I don't know what to tell you at this moment. – Programmer Oct 05 '17 at 20:54
  • @Programmer OK, thought maybe there is some other solution that will give us the ability to ship several assetbundles with the build, and to be able to update those assetbundles later on and with no memory duplication... – Tomer Peled Oct 05 '17 at 21:02
  • 1
    @TomerPeled No. You can have many AssetBundles shipped with your game but cannot update it. Any Unity function that looks like it is updating it is only making a copy or downloading a new one. – Programmer Oct 05 '17 at 21:05
0

You 'dont' keep a local text file. you have the version number inside the local bundle. You have a text file on the server. then get the text file, compare that with the version in the bundle and update if necessary.

In the server, you can have an assetbundle with only a textasset to secure that too.

you can build the asset bundles and have them in the streamingAssets folder or anywhere and use AssetBundle.LoadFromFile()

Suraj S
  • 1,019
  • 7
  • 18
  • I thought the version number is not in the local bundle, it is just a random number for UnityWebRequest.GetAssetBundle to grab update for server? – weijia_yu Jul 06 '17 at 03:26
  • What i meant by `you have the version number inside the local bundle` is that you create a TextAsset indicating version and other properties of the assetBundle and package it along with the bundle. @ywj7931 – Suraj S Jul 06 '17 at 03:32
  • That way, others cant modify it since its not a text file – Suraj S Jul 06 '17 at 03:34