The AssetDatabase has been rewritten. The more you know about how this API works, the stronger your code will be. This information can guide your decision-making for your own Asset Management strategies. For example, you do not need to reimport assets when you jump between platforms. In this session, you'll gain a deeper understanding of importing modified assets and tracking dependencies to improve your workflow and iteration time significantly.
Speaker: Javier Abud Chavez- Unity
Watch the session on Youtube: https://youtu.be/S2P9n5U9xVw
3. Overview
3
Intro to new AssetDatabase
What happens when you Refresh()
Ideas behind Fast Platform Switch
Tips and tricks of ADB
Q&A!
4. About me
4
Been making games since 2004
Have worked on PS2, Nintendo DS, MMORPGs for PC, many Flash
Games, Android, iOS
Been with the Asset Pipeline team for a year now
6. Re-written AssetDatabase
6
— API Compatibility with Version 1
– Updated API reference to have more code examples!
— Guiding Principles:
– Determinism
– Dependency tracking
– Deterministic importers
— Will mention Cache Server in this talk, but won’t go into too much detail
– Supports dynamic dependencies
7. AssetDatabase Jargon
7
— Import Results & Artifacts
Artifacts/
Library/
0a3d2c7a0e9410b7e6a0603db99202d2
9c261a0511b00763080511c82b43dd93
...
0a/
9c/
— This is what is stored in the Library folder
— Terms are interchangeable
8. AssetDatabase Jargon
8
— Hashing
– In the context of the AssetDatabase
– Taking an arbitrary data stream and producing a 128 bit Hash from it
Array of bytes:
41 73 73 65 74
44 61 74 61 62
61 73 65 2E 47
65 74 42 75 69
6C 74 69 6E 45
78 74 72 61 52
65 73 6F 75 72
Hashing
128 bit Hash:
0a0086cbb18a3416
b88c52e7b8a6fc84
9. 1
— Dependencies
– Things we determine that could have an effect on the
import result
9
Dependencies
2
3
...
Import
Import
Result
AssetDatabase Jargon
10. 10
— Dependency tracking
– Static and Dynamic dependencies
– More on these later
1
Dependencies
2
...
Import
Import
Result
AssetDatabase Jargon
11. 11
— Determinism
– We give you the confidence that for a particular input the
same output is always* produced
public void NonDeterministic(Object asset, string path01, string path02)
{
AssetDatabase.CreateAsset(asset, path01);
var result = AssetDatabase.MoveAsset(path01, path02);
Debug.Log(result);
}
public void Deterministic(Object asset, string path01, string path02)
{
if (AssetDatabase.AssetPathToGUID(path01) != string.Empty)
AssetDatabase.DeleteAsset(path01);
if (AssetDatabase.AssetPathToGUID(path02) != string.Empty)
AssetDatabase.DeleteAsset(path02);
AssetDatabase.CreateAsset(asset, path01);
var result = AssetDatabase.MoveAsset(path01, path02);
Debug.Log(result);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
AssetDatabase Jargon
12. 12
— Deterministic importers
– Ensure that when importing an Asset, the Import Result is
the same given all the dependencies are the same
– Same across machines
– Very important for Caching data remotely
AssetDatabase Jargon
13. 13
The AssetDatabase
— AssetDatabase split into 2 Databases
– Source Asset Database
– Artifact Database
— Memory mapped Databases
– Transactional, so harder to corrupt
14. 14
Source Asset Database
— Contains information about your source assets
– Last modified date
– 128 bit Hash of source file
– GUIDs
– Other meta-information
15. 15
Artifact Database
— Information about the import results
— Each entry contains
– Import dependency information
– Artifact meta information
– List of artifact file paths
– .info files
– .res files
18. 18
There are multiple ways to trigger a refresh
– Auto-refresh
– Assets -> Refresh (Menu Item + Shortcut)
– From C#: AssetDatabase.Refresh();
– Various APIs calls that trigger a Refresh internally
What is a Refresh?
24. 24
— Enumerate files in Assets folder
– Detect changed files
– Hash content of changed files, store in
database
— Enumerate all files Packages folder
– Hash content of files, store in database
– Only done once, as Packages are immutable
Assets/
hash(content)
com.unity.ai/
com.unity.foo-bar/
hash(content)
hash(content)
hash(content)
Scan
25. 25
— Generate a list of all relevant assets
— Upcoming feature: Directory Monitor
– Talk tomorrow by Jonas Drewsen: Speed up your asset
imports for big projects
Scan
26. 26
— Purpose
– Determine if the dependencies of an Asset are up to date
– Usual split by
– Source Code
– Source Assets
– Necessary to have this split as code may affect imports
— Matching the Asset
– Static dependencies
– Dynamic Dependencies
Categorize Assets
27. 27
— What are static dependencies?
– Things we know ahead of time
Static Dependencies
Static Dependencies
Asset Name
Importer ID
Importer Version
Build Target
36. 36
— Assembly Reload
– Restart Refresh if necessary
– Here’s where you can start seeing see Iteration … on
the progress bar
Compile & Assembly Reload
38. 38
— You receive
– Imported Assets
– Deleted Assets
– Moved Assets & Moved From Asset Paths
— Changes here can cause unintentional iterations to be triggered
– AssetDatabase.ForceReserializeAssets()
– AssetImporter.SaveAndReimport()
Post Process All Assets
39. 39
At least for the Refresh side of things!
— Scan
— Categorize Assets
— Compile Scripts
— Import
— Post Process All Assets
That’s all!
41. 41
— QA found a bug on Android
– Your project is currently on PC
– Take at least ~30mins to switch platforms
— QA found another bug on PC!
– Switch back to PC
– Wait at least another ~30mins to re-import project
— Light at the end of the tunnel!
Scenario
42. 42
— Any changes to dependencies will result in a new file
– Switching platforms changes (usually) one dependency
– Library folder made up of import results with Hash as their file name
– We keep Import Results around
– With occasional garbage collection (upon restart of Unity)
— The in memory database tracks these hashes
Hash is the File Name
43. 43
Static Dependencies
Asset Name
Importer ID
Importer Version
Build Target
Dynamic Dependencies
Color Space
Graphics API
Scripting Runtime
Version
Hash of Source Asset
Texture Compression
State
Gathering Dependencies
48. 48
— What happens to the import result if I modify my asset?
– With AssetDatabase V1
– Artifact path was based on the GUID
– Example:
– Prefab03.prefab.meta
– guid: f0374bcd9f7348540a29154e223c8ff1
Tips & Tricks of the AssetDatabase
Modify
Prefab03.prefab
Artifacts/
Library/
f0374bcd9f7...
f0/
Artifacts/
Library/
f0374bcd9f7...
f0/
49. 49
— What happens to the import result if I modify my asset?
– With AssetDatabase V2
– Artifact path is the Content Hash
– If your asset changes, a new File will be generated
– Content Hash: 61cd23f1db101a0956eb0a15ff67fbb1
Tips & Tricks of the AssetDatabase
Artifacts/
Library/
a5f54bcd9f7...
a5/
Modify
Prefab03.prefab
Artifacts/
Library/
61cd23f1db...
61/
50. 5050
— Experimental feature: AssetDatabase Counters
– Expose more information the state of the AssetDatabase
– Import Counters
– Assets imported (application lifetime)
– Number of refreshes
– Number of Assembly Reloads
– Delta & Total for each field
– Cache Server counters available too!
Tips & Tricks of the AssetDatabase
51. 51
— AssetDatabase Counters Usage
using UnityEditor.Experimental;
public void FooBar()
{
var countersBefore = AssetDatabaseExperimental.counters.import;
var totalImported = countersBefore.imported.total;
Debug.Log("Total imported assets: " + totalImported);
var textAsset = new TextAsset("test");
var savePath = "Assets/textAsset.txt";
AssetDatabase.CreateAsset(textAsset, savePath);
var countersAfter = AssetDatabaseExperimental.counters.import;
totalImported = countersAfter.imported.total;
Debug.Log("Newly imported asset count: " + totalImported);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Tips & Tricks of the AssetDatabase
52. 52
— AssetDatabase.CreateAsset()
- Slow because of callbacks
public void Bar(Object[] assets, string[] paths)
{
for(int i = 0; i < assets.Length; ++i)
{
AssetDatabase.CreateAsset(assets[i], paths[i]);
}
...
}
1
2
3
4
5
6
7
8
- Main Issue
- Callbacks being triggered
- OnPostProcessAllAssets called N times
- Pre/PostProcessor Callbacks invoked
Tips & Tricks of the AssetDatabase
53. 53
Batching CreateAsset
public void Baz(Object[] assets, string[] paths)
{
try
{
AssetDatabase.StartAssetEditing();
for(int i = 0; i < assets.Length; ++i)
AssetDatabase.CreateAsset(assets[i], paths[i]);
}
finally
{
AssetDatabase.StopAssetEditing();
}
...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
- StartAssetEditing puts AssetDatabase into wait state
- StopAssetEditing tells AssetDatabase an import can begin
- Pending assets are imported, Callbacks are triggered
Tips & Tricks of the AssetDatabase
54. — For certain workflows, you might want to ignore a folder and its
contents
– Adding a “~” at the end of a folder name will ignore it and its contents
54
Materials/
Assets/
Materials~/
Will be imported
Will be ignored
Tips & Tricks of the AssetDatabase
55. 55
— Asset Database Rewritten
— Refresh and Importing
— Fast Platform Switch
— Tips and tricks
— Now available on 2019.3 Beta!
Summary