I spend a lot of time writing ScriptedImporters so that various generated parts of our game are cacheable and update automatically. This works great for the most part!
One of my common needs, though, is to create a generated asset that depends on an entire folder of other assets. For example:
- An Icon packer that creates an atlas and Sprite objects for every icon in a folder.
- A database asset that stores various metadata for a bunch of prefabs.
- An importer that generates new prefabs for each prefab in a folder (ie. Normal & Blueprint).
- A database asset to collect all Prefabs that can be spawned at runtime, so they can be baked for ECS.
Right now, in all of these use cases we have a big “Update” button on each of the ScriptedImporters that manually builds a list of dependencies, but this can hit merge conflicts when many people are updating it.
Of course, you can scan the folder on import and add each file, but that doesn’t trigger a reimport when a new file is added to the folder.
Dependencies on folders are possible in a lot of build systems, but I haven’t found a way to do this with Unity’s. Is there some way I’ve been missing? I’m deep in the internals of the Asset Database, so even if it’s advanced I’d love to know.
If not, this feature would really advance the state of a lot of generated asset workflows!
Why not?
You can monitor these changes with OnPostprocessAllAssets and depending on the asset path and whether it was a create, import, move or delete you perform the necessary actions for it.
Or is that folder outside the Assets tree? If so, you may want to look into Directory Monitoring API which I think is available in the editor.
For an „advanced“ use-case, actually it‘s more commonly simply unexpected / not considered an asset: you can LoadAsset a path to a folder. Yes, folders are valid assets too. That may help for instance via Path.GetDirectoryName which you can load the folder path of an asset and compare its GUID with one you have in your registry of paths to monitor. Avoids doing possibly brittle path string comparisons.
OnPostprocessAllAssets doesn’t really scale well. It only runs at the end of the import, so if you make asset changes, it must trigger another import phase. While this is fine for a quick hack, once you have 10-20 of these, you can stumble into a huge number of reimport phases (or worse, a cyclical import loop). It’s very heavy weight, and executes for all assets, all the time, regardless of whether there was important work that needs to be done. Unity has been moving away from this style of Asset importing for a while.
The new Asset Database v2 is a build graph, more like a compiler. It only does the work that’s absolutely necessary, which is important for keeping things snappy when you’re generating a lot of assets. This is great, we just need a ctx.AddDirectoryDependency(path) API so we can register for a reimport when files in a directory are changed.