Unity 在AssetPostprocessor内使用AssetDataBase是不安全的行为(尤其在Build前进行Library的删除)

发布时间 2023-07-05 18:40:26作者: sun_dust_shadow

https://docs.unity3d.com/Manual/AssetDatabaseCustomizingWorkflow.html

在Build前进行Library的删除,读取Asset是不安全的行为,需要使用C#的IOSystem进行操作

Asset Import Order

If you are scripting using the AssetDatabase class, it’s important to understand how the order of Unity’s import processes can affect your scripts, otherwise you may get unexpected results. The order is as follows:

  1. Import Script Assets (.cs, .dll, .asmdef files)
  2. Compilation
  3. Domain reload
  4. InitializeOnLoad callback
  5. Import all other assets

Scripts are always imported and compiled before all other regular assets, because the Editor needs to know whether there are custom asset post-processors or scripted importers in the project. This ensures that the Editor uses any new or changed importers or post-processors when importing the rest of the non-script assets.

The InitializeOnLoad callback is often used to run some code on project startup or when scripts change. As shown in the list above, this callback is run after Unity reloads the domain, but before it starts importing assets. This means if you’re using the [InitializeOnLoad] callback to access assets, your code is executed before the current asset import cycle completes. In particular:

  • For assets being imported for the first time, methods like AssetDatabase.LoadAssetAtPath, AssetDatabase.FindAssets, Shader
    .Find, Resources.Load will return null, since those assets have not yet been imported. 

  • For assets that have already been imported at least once, methods like AssetDatabase.LoadAssetAtPath, AssetDatabase.FindAssets, Shader.Find, Resources.Load will return the previous (outdated) version of the asset if it was modified before reloading the domain, since domain reload occurs before the regular asset import phase.

When you are writing scripted importers, asset pre-processors, and asset post-processors, you should not make your code assume that other specific assets are already imported according to any particular order. When importing, Unity groups assets into queues by type, and while the types are imported in a predefined order, assets within a queue of the same type are imported in an arbitrary order unless you use ScriptedImporter.GatherDependenciesFromSourceFile. Using GatherDependenciesFromSourceFile also creates a dependency between the assets, so if one asset is modified, the other that depends on it is reimported.