I’ve spent a great deal of time with the AssetDatabase. Ultimately I wrote an entire new API for it since it’s so messy and confusing.
I want to clarify what commonly used AssetDatabase method calls actually do. Because there is a tendency to either “experiment” or copypasta scripts - in both cases often leading to superfluous calls, complex scripts, degraded editor performance (which then gets blamed on Unity).
Do note that every extraneous AssetDatabase method call incurs a performance penalty. You ARE dealing with operations that write to or read from the file system, possibly even a spinning magnetic drive.
Perhaps even with an antivirus scanner readily waiting to analyze those byte streams … but that’s another story, a short one: exclude the project folder(s) from any antivirus’ online/live scans!
AssetDatabase.Refresh
The correct name for this method ought to be: AssetDatabase.ImportAllAssets
Or to be perfectly accurate: AssetDatabase.ImportAllAssetsAndUnloadUnusedResources
You can see why you ought to avoid calling that!
Refresh does its job alright (eg it imports assets and refreshes the GUI) but it comes at a cost and that means Unity is forced to reload assets from disk if they were currently unused. This can slow down your editing experience.
You NEVER need to call Refresh after modifying assets exclusively via AssetDatabase methods!
So when do you need to call Refresh?
Very rarely! For instance after you ran a batch operation over your project that may have modified assets and you have asset auto-refresh disabled and you don’t know which ones had been modified, then you Refresh.
In cases where you do these asset modifications yourself within the editor but not without AssetDatabase methods, well, in that case you know the assets you modified. So you import those specifically. See:
AssetDatabase.ImportAsset
A better name for this would be: ImportExternallyModifiedAsset
You only ever need to call this if you created or modified a project file through any means OTHER than via AssetDatabase methods!
For example when you create or modify an asset file with File.WriteAllText you call ImportAsset on that file to make it known to the AssetDatabase and available in the editor. If you forget to call ImportAsset on a System.IO modified/created file and try to load that asset, it will return null.
Note (repeat): Any AssetDatabase method calls will automatically have the current version of the asset already imported.
AssetDatabase.CreateAsset
This creates an asset file on disk.
The asset file is saved and imported. The asset file has been written to disk. All of the asset’s state is persisted on your file system. Do I need to go on? There is no need whatsoever to “save” the asset after you created it. It isn’t somehow “created but not saved”, lingering partially unsaved in memory or some other mysterious voodoo.
Nor do you need to call ImportAsset on a newly created asset.
If you modify an asset after you created it, it does not need saving either! That’s because you ought to apply the modifications FIRST, then create the asset. I know this seems crazy to some. ![]()
AssetDatabase.DeleteAsset
This deletes an asset file or folder. Folders are assets, too! At least those under /Assets …
I include this here because some people (explicitly not: developers) mysteriously follow-up DeleteAsset with SaveAssets. ![]()
AssetDatabase.SaveAssets
This is equivalent to File => Save Project.
Only call this if you really mean to save the project! Like … everything!! Including any unsaved modifications to prefabs, scenes, and so on that the user may not want to have saved at this point.
Don’t call this merely because you changed one or more assets. Use AssetDatabase.SaveAssetIfDirty instead on each individual asset that was changed. Don’t be lazy, be specific!
AssetDatabase.ForceReserializeAssets
This should not be used unless you know (!) that you need to use it.
How do you know?
Well, there’s only one use case for this: if you are a version control user, and you work with a team, and you want to upgrade the project’s editor version, and you want asset modifications to only show the user’s changes in changelists.
In that case, you would run a script - after updating the editor version - that calls ForceReserializeAssets on all or a selection of assets to forcibly reserialize them in the latest asset file format. Then you commit your modifications and let the team start working with the new editor version.
It is NOT a catch-all “make sure that things are saved” kind of method. Although it has that effect, you ought to consider why this is an issue for you and instead fix that. Perhaps you merely forgot to call EditorUtility.SetDirty on the object that wouldn’t get saved?
AssetDatabase.StartAssetEditing
This provides a gigantic speed-up of batched asset file operations. Gigantic as in: what used to take 30 seconds now completes in a second! Begone, Hold On …
The operations that can be batched are creating, saving, copying, moving, and importing assets. Generally any operation that modifies files on disk benefits from this. System.IO methods will NOT be sped up however but the necessarily following ImportAsset calls will be batched.
Do note that created or imported assets will NOT be available until after you call StopAssetEditing. Any attempt at loading an asset that was created or imported between Start/Stop will return null.
CAUTION: It is mandatory (!!) to enclose these calls with a try/finally block as follows - failure to do so will lead the editor unable to import any assets until you restart the editor if the code throws an exception.
try
{
AssetDatabase.StartAssetEditing();
// create, copy, move, import, save, etc. multiple assets via AssetDatabase here ...
}
finally
{
AssetDatabase.StopAssetEditing();
}