Wednesday, January 10, 2024

Unity Addressables Content Catalog Refresh

 We're using Unity's Addressables to implement DLC for a multi-platform game, and on certain platforms, we don't actually know the path to the DLC until after it's loaded, which could be some time after the game has started.  One method is to use a multiple catalog system, like this one developed by LuGus-Jan and pdinklag.  In our case, though, we wanted to stick to a single catalog system if at all possible, and we were able to come up with a way to refresh the Addressables content catalog at runtime, though normally Unity does it once when the game starts up.  The code is written against Unity Addressables 1.19.19.

Refresh Addressables Content Catalog

The Addressables system allows you to specify code to dynamically construct load paths at runtime, but those paths are resolved to strings during the initial content catalog load, and take whatever value the code returns at that point.  Using this refresh operation, we can update the return value for the DLC path later while the game is running, and then force the Addressables system to re-resolve the paths to their correct values.  Addressables can then be accessed from the DLC as expected.

The public method for loading an Addressables content catalog is made assuming that data is being downloaded from the internet, and so includes an automatic caching feature to avoid redundant downloads.  However, the feature involves writing to Application.persistentDataPath, which is not allowed on some platforms.  For those cases, there is an alternate version that uses .NET reflection to access the internal methods and duplicate the same process, but avoid the step of reading and writing to the cache.  This may need to be revised with future versions of the Unity Addressables package.

Unity Addressables Per-Platform Group Settings

While developing a project for multiple platforms, we've encountered issues where the recommended packing settings for Addressable Groups differs, particularly when it comes to compression.  Some platforms don't natively compress the final package, so it's useful to compress the Addressable packed assets to keep the overall file size down.  Other platforms have recommended packing settings to help with patching.  In some cases, having uncompressed Addressable packed assets is ideal for patching.  There's currently no way of specifying different packing settings per platform (as of Unity Addressables 1.19.19).  Unity is aware of the need for this, but we have not seen any public progress on it.

In the mean time, we've come up with a relatively straightforward way to handle this situation so that we don't have to manually change settings when switching platforms.  In short, we have a new Addressable Group schema to apply where we can specify overrides for particular packing settings per platform, and a new Addressables build script that looks for this schema and replaces the actual packed schema with the overrides, if appropriate.

The code is available here.

In addition to the code, there are several more manual steps that need to be taken before things become fully automated.
  1. Create a new PlatformBuildScriptPackedMode Addressable Data Builder and (ideally) place it in Assets/AddressableAssetsData/DataBuilders.
  2. Register this new Addressable Data Builder with the Addressables Settings.  In your Addressable Asset Settings, add the new PlatformBuildScriptPackedMode asset to the list of "Build and Play Mode Scripts".

  3. Now go to individual Addressable Groups and add the new PlatformBundledAssetGroupSchema to each Group that needs an override.

  4. To actually build correctly, you need to select the new Platform Build Script Packed Mode builder from the Addressables build menu.

This should cover all the basics for using the platform overrides.  If you want to automate builds and select the proper builder, we recommend following this example from Unity.

You can add more platforms as needed when you use the code, as well as more overrides for your specific use case.  Right now, this schema does not support multi-editing, though that would be a very useful feature for future development.