0
\$\begingroup\$

Suppose that you have thousands of individual resources that need to be loaded dynamically (e.g. some kind of procedural or randomized world that spawns all manner of things etc). There are many ways you could manage the resource loading, like Resources, or AssetBundles, or Addressables, etc.

There is another option, which involves putting your asset data together into "block" files. This is done notably in Genshin Impact, if you look at their StreamingAssets folder. I would like to learn more about how this is typically implemented in the context of Unity, but cannot find many resources online about it.

Off the top of my head, this could be as simple as having an index table file to locate individual assets and then use file streams on the blocks to Seek() as needed and then load the bytes to build the assets, but I feel there may be more to it than just that: for example, there is specific folder structure separating the .blk files (folders going 00, 01, 02 etc instead of just putting all the blocks together and whatnot).

What is the typical way of authoring and implementing dynamic assets via blocks, in Unity? Are there guides/resources about this approach?

\$\endgroup\$
4
  • 2
    \$\begingroup\$ I suspect it would be difficult to beat the performance of addressables. \$\endgroup\$
    – Adam B
    Feb 11 at 6:05
  • \$\begingroup\$ AssetBundles are effectively blocks — groups of related assets packed together with manifest information to help locate specific needed assets within the collection. What specifically is it that you want to do, that you have not found a way to do with the Addressables or AssetBundles that you've mentioned? \$\endgroup\$
    – DMGregory
    Feb 11 at 10:26
  • \$\begingroup\$ @DMGregory the issue I run with AssetBundles for this kind of "dynamic" game is that some scenarios involving plenty of "variety" will cause lots of IO operations opening/closing the individual bundles (and I can't just bundle many assets into one bundle since there's no way of knowing beforehand if they will really appear together etc). That IO burden is noticeable on some platforms, and I had discarded Addressables because from my understanding they're just AssetBundles as well. Genshin using blocks made me think that it was a good way to tackle the dynamic nature of the game. \$\endgroup\$
    – Oxide
    Feb 11 at 23:08
  • \$\begingroup\$ Can you elaborate on what you think the difference is and why blocks would be better? Both blocks and asset bundles are systems of packing together asset into logical cluster files that can be dynamically loaded and the individual assets peeled out. Why would calling the cluster file a "block" result in less file I/O than calling it a "bundle"? \$\endgroup\$
    – DMGregory
    Feb 11 at 23:12

1 Answer 1

1
\$\begingroup\$

The currently (2022) recommended way of doing this would be Addressable Assets.

The addressables system allows to organize assets in asset bundles by assigning them to "Groups". Asset bundles are archive files containing multiple assets. In order to optimize loading times, you usually should try to group each asset together with its dependencies (like a 3d model together with its textures) and also group assets together which are frequently loaded together (like all environment dodads which occur in the same biome). More about finding an ideal organisation strategy for your asset bundles can be found in the documentation section Organizing Addressable Assets.

However, there might still be some specialized cases where it can indeed make sense to build your own system. For example, when you have a very large open world map with long viewing distances which does not use the Unity terrain system and thus needs to be constructed and destroyed at runtime in various levels of detail as the player explores it (like in Genshin Impact, for example). In that case it can be useful to invent your own file format for storing map chunks. But as I said, you are dealing with a very special use-case here, which requires a very special solution tailor-made for the specific requirements of your game.

For example, you could have a solution which stores different levels of detail of each block in separate files. Or one where each block starts with the lowest-detail data and then continues with higher and higher detail versions. So the file parser can just stop reading as soon as it reached the desired level of detail. This could be accomplished pretty elegantly by storing the world geometry data in a spatial tree and serializing it in a breadth-first manner. But that's just one option of many. Again, there is no one-size-fits-all standard solution here. Your solution would be driven by how your custom terrain system works and by your specific requirements.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .