はじめに
AssetDatabase
はアセットの作成・削除・移動・コピーなどの操作をすることができます。特に大量のアセットに大して操作を行ったりすると、なかなか処理が終わらずにパフォーマンス上の問題がでてきたりします。
docs.unity3d.com
そこでAssetDatabase.StartAssetEditing
・AssetDatabase.StopAssetEditing
を用いることで、複数のアセット操作を一度の処理で行うように指示することができます。
また今回はそれらをより安全に活用できるようにしたAssetEditingScope
について紹介したいと思います。
StartAssetEditingとStopAssetEditingについて
StartAssetEditing()
を呼び出すと、一時的にAssetDataabase
の操作が行われなくなります。そしてStopAssetEditing
を呼び出すことでStartAssetEditing
〜StopAssetEditing
の間に行った変更をバッチ処理します。デフォルトでは各変更を順番に処理して毎回アセットの完全な更新処理を実行するのに対し、一連の操作を最後に一度だけ処理を行うようにすることで処理時間を大きく削減できるというわけです。
try { AssetDatabase.StartAssetEditing(); AssetDatabase.CopyAsset("Assets/SourceFolder/MyTexture.png", "Assets/DestinationFolder/MyTexture_copy.png"); AssetDatabase.MoveAsset("Assets/SourceFolder/MyMaterial.mat", "Assets/DestinationFolder/MyMaterial_moved.mat"); } finally { AssetDatabase.StopAssetEditing(); }
またネストされている場合には、内部にカウンターを持っているのでStartAssetEditing()
を実行した回数だけStopAssetEditing()
を呼ぶ必要があります。
AssetDatabase.StartAssetEditing(); // Counter = 1 //... アセット操作... AssetDatabase.StartAssetEditing(); // Counter = 2 //... アセット操作... AssetDatabase.StopAssetEditing(); // Counter = 1 (まだインポートは再開されない) //... アセット操作... AssetDatabase.StopAssetEditing(); // Counter = 0 (ここでインポートが再開される)
ちなみにStopAssetEditing
をStartAssetEditing
以上に呼び出してしまうと、以下のようなエラーがでてきます。
Assertion failed on expression: 'gRefreshReentrancyCount > 0' StopAssetEditing invoked without a call to StartAssetEditing. Please make sure that for every call to StopAssetEditing there is at least one call to StartAssetEditing
AssetEditingScopeについて
IDisposable
を実装して、using
を用いることでStartAssetEditing
・StopAssetEditing
を確実に行えるようにしたAssetEditingScope
がUnity 2023.1.0f1より登場しました。
github.com
2023.1.0f1
Added: Added AssetDatabase.AssetEditingScope().
Unity Release Notes (Alpha) - Search
using (var editingScope = new AssetDatabase.AssetEditingScope()) { AssetDatabase.CopyAsset("Assets/CopyAsset.txt", "Assets/Text/CopyAsset.txt"); AssetDatabase.MoveAsset("Assets/MoveAsset.txt", "Assets/Text/MoveAsset.txt"); }
AssetEditingScope - Unity スクリプトリファレンス
安全性とコードの明瞭性の観点から可能な限りAssetDatabase.AssetEditingScope
を使用して、StartAssetEditing/StopAssetEditing
を直接使用する場合は、try...finally
を必ず利用するようにすると良いでしょう。