The AssetDatabase
class has methods that allow you to access and perform operations on assets in the same way the Unity Editor does. You can create, import, delete, copy, move, load, and save assets, and search the asset database.
This means you can create anything from simple adjustments to powerful tools and customizations to your project’s asset workflow, using Unity’s Editor scripting and Editor window customization.
For the full list of methods available, and documentation for each of the methods, refer to the AssetDatabase
API reference.
You can use batching to save time when making changes to assets from code. If you make changes to multiple assets, the Asset Database’s default behavior is to process each change in turn, and perform a full refresh process for the asset before moving on to the next line of code.
The following example changes three assets, copying Asset1
, moving Asset2
, and deleting Asset3
:
AssetDatabase.CopyAsset("Assets/Asset1.txt", "Assets/Text/Asset1.txt");
AssetDatabase.MoveAsset("Assets/Asset2.txt", "Assets/Text/Asset2.txt");
AssetDatabase.DeleteAsset("Assets/Asset3.txt");
Without batching, Unity processes each change before moving on to the next line of code. This takes an unnecessarily long time and triggers many callbacks.
To save time you can use the AssetDatabase
APIs to pause automatic asset importing, define a series of asset operations in your code, and then resume automatic importing. On resumption, the Asset Database processes your defined asset operations as a batch, which is faster than processing them one by one.
For more details and an example implementation, refer to the AssetDatabase.StartAssetEditing
API reference.
Asset files can contain multiple serialized objects, each of which can be considered an asset for the purposes of scripting with the AssetDatabase
class. For example, a .prefabAn asset type that allows you to store a GameObject complete with components and properties. The prefab acts as a template from which you can create new object instances in the scene. More info
See in Glossary asset file could contain a serialized GameObjectThe fundamental object in Unity scenes, which can represent characters, props, scenery, cameras, waypoints, and more. A GameObject’s functionality is defined by the Components attached to it. More info
See in Glossary with multiple components attached. Each of those components are also serialized as objects in the asset file, and so when accessing the contents of the prefab asset using AssetDatabase
methods, the component objects within the asset file are considered sub-assets.
When asset types contain more than one serialized asset object, Unity treats one of the assets as the main asset. The main asset is always the first asset added to the file, unless otherwise specified with the SetMainObject
method.
The Editor displays some types of sub-assets in the project windowA window that shows the contents of your Assets
folder (Project tab) More info
See in Glossary. In the following example, an FBX asset file containing a Space Frigate
model is expanded in the Project window to reveal a material and a meshThe main graphics primitive of Unity. Meshes make up a large part of your 3D worlds. Unity supports triangulated or Quadrangulated polygon meshes. Nurbs, Nurms, Subdiv surfaces must be converted to polygons. More info
See in Glossary as sub-assets:
Some sub-asset types don’t show in the Project window. For example, the Space Frigate
asset file in the previous example actually contains more than the two sub-assets displayed in the project window. You can see the real number of assets when you access the asset file using AssetDatabase
methods, as demonstrated in the following example:
using UnityEngine;
using UnityEditor;
public class Example : MonoBehaviour
{
[MenuItem("AssetDatabase/InspectAssets")]
private static void InspectAssets()
{
Object[] data = AssetDatabase.LoadAllAssetsAtPath("Assets/Space Frigate.fbx");
Debug.Log(data.Length + " Assets");
foreach (Object o in data)
{
Debug.Log(o);
}
}
}
In this case, the output shows that the imported, serialized version of this file contains six assets:
6 Assets
Space Frigate (UnityEngine.GameObject)
space_frigate_0 (UnityEngine.Material)
space_frigate_0 (UnityEngine.Mesh)
Space Frigate (UnityEngine.Transform)
Space Frigate (UnityEngine.MeshRenderer)
Space Frigate (UnityEngine.MeshFilter)
This is because the GameObject, material, the mesh data itself, and each of the components that Unity automatically added to the GameObject during the import process (the Transform, the MeshFilter, and the MeshRenderer), each count as a separate serialized object. Therefore they are sub-assets of the asset file, and as far as the AssetDatabase
API is concerned, are each a separate asset.
The asset import order has some important implications for your code. ScriptsA piece of code that allows you to create your own Components, trigger game events, modify Component properties over time and respond to user input in any way you like. More info
See in Glossary are always imported and compiled before all other non-default assets, because they can include custom asset post-processors or scripted importers that are used later to import non-script assets.
The [InitializeOnLoad]
attribute is a common way to run code on project startup or when scripts change. This callback runs after domain reload, but before import of non-script assets. Methods such as AssetDatabase.LoadAssetAtPath
that rely on the asset being imported won’t work as intended if called from [InitializeOnLoad]
. They will return null for assets being imported for the first time, and return the outdated version of assets being reimported.
Code for custom scripted importers, asset pre-processors, and asset post-processors should not rely on specific assets being imported in a determined order. The import process groups assets into queues by type. The types are imported in a predefined order, but the import order among assets of the same type is not deterministic, unless you use ScriptedImporter.GatherDependenciesFromSourceFile
. Using GatherDependenciesFromSourceFile
also creates a dependency between the assets, so modifying an asset triggers reimport of any assets that depend on it.
Note: Default assets are imported by the built-in DefaultImporter before script assets, so any script-defined OnPostProcessAllAssets
won’t run for default assets.