Вы можете использовать пакетную обработку, чтобы сократить время и время обработки при внесении изменений в ресурсы в вашем коде.
Если вы вносите изменения в несколько объектов в своем коде (например, копируете или перемещаете файлы ресурсов), поведение базы данных объектов по умолчанию заключается в обработке каждого изменения по очереди и выполнении полного процесса обновления для объекта перед переходом к следующая строка кода.
В приведенном ниже примере изменены три объекта. Ресурс1 копируется, Ресурс2 перемещается, а Ресурс3 удаляется:
AssetDatabase.CopyAsset("Assets/Asset1.txt", "Assets/Text/Asset1.txt");
AssetDatabase.MoveAsset("Assets/Asset2.txt", "Assets/Text/Asset2.txt");
AssetDatabase.DeleteAsset("Assets/Asset3.txt");
Без пакетной обработки Unity обрабатывает каждое изменение, прежде чем перейти к следующей строке кода. Это не только занимает неоправданно много времени, но и запускает множество обратных вызовов, которых можно избежать, если использовать пакетную обработку.
Вместо этого вы можете указать, что база данных активов должна обрабатывать группу операций одновременно. Для этого вам нужно указать базе данных активов приостановить ее обычное поведение, прежде чем вы внесете изменения, а затем возобновить ее после завершения ваших изменений.
В частности, вам следует попытаться использовать пакетную обработку, если вы выполняете более одной из следующих операций:
- AssetDatabase.ImportAsset
- AssetDatabase.MoveAsset
- AssetDatabase.CopyAsset
- AddObjectToAsset
Методы обработки операций
Чтобы указать, что база данных активов должна обрабатывать группу операций одновременно, вы можете использовать следующие методы: AssetDatabase.StartAssetEditing и AssetDatabase.StopAssetEditing.
AssetDatabase.StartAssetEditing
Этот метод сообщает базе данных активов, что вы начинаете вносить изменения в активы. База данных активов переходит в состояние паузы и не обрабатывает никаких дальнейших изменений в ваших активах, пока вы не вызовете соответствующий метод StopAssetEditing, чтобы сообщить ему, что вы закончили.
AssetDatabase.StopAssetEditing
После внесения всех изменений в активы вызовите этот метод, чтобы указать базе данных активов обработать ваши изменения и немедленно вернуться к обычному режиму автоматической обработки изменений. Затем база данных активов обрабатывает изменения, сделанные вами между StartAssetEditing
и StopAssetEditing
, в пакетном режиме, что происходит быстрее, чем если бы они были обработаны. по одному.
Вложенные вызовы StartAssetEditing и StopAssetEditing
Если вы делаете более одного вызова StartAssetEditing
, вы должны сделать соответствующее количество вызовов StopAssetEditing
, чтобы База данных активов возобновляет нормальное поведение автоматической обработки изменений.
Это связано с тем, что эти функции увеличивают и уменьшают счетчик, а не действуют как простой переключатель включения/выключения. Вызов StartAssetEditing
увеличивает счетчик, а вызов StopAssetEditing
уменьшает счетчик. База данных активов возобновляет свою нормальную работу, когда счетчик достигает нуля.
Причина, по которой Unity использует счетчик, а не простое логическое значение включения/выключения, заключается в том, что если ваш код выполняет несколько вложенных пар «старт» и «стоп», внутренние пары случайно не активируют нормальное поведение базы данных активов. рано. Вместо этого каждая пара увеличивает и уменьшает счетчик на единицу, и если ваш код правильно вложен, последний внешний вызов StopAssetEditing
устанавливает счетчик на ноль.
Примечание. Ваш код никогда не должен заставлять счетчик опускаться ниже нуля. При этом возникает ошибка.
Пример
В следующем примере показан рекомендуемый способ использования этих методов:
using UnityEditor;
public class StartStopAssetEditingExample : MonoBehaviour
{
[MenuItem("APIExamples/StartStopAssetEditing")]
static void CallAssetDatabaseAPIsBetweenStartStopAssetEditing()
{
try
{
//Place the Asset Database in a state where
//importing is suspended for most APIs
AssetDatabase.StartAssetEditing();
AssetDatabase.CopyAsset("Assets/Asset1.txt", "Assets/Text/Asset1.txt");
AssetDatabase.MoveAsset("Assets/Asset2.txt", "Assets/Text/Asset2.txt");
AssetDatabase.DeleteAsset("Assets/Asset3.txt");
}
finally
{
//Adding a call to StopAssetEditing inside
//a "finally" block ensures that the AssetDatabase
//state will be reset when leaving this function
AssetDatabase.StopAssetEditing();
}
}
}
Использование try…finally для редактирования объектов
Когда вы вызываете AssetDatabase.StartAssetEditing
, Unity переводит всю базу данных AssetDatabase редактора в состояние паузы. Таким образом, если вы не сделаете соответствующий вызов AssetDatabase.StopAssetEditing
, редактор не будет реагировать на любые операции, связанные с активами (импорт, обновление и т. д.). ) и требует перезапуска редактора для восстановления нормальной работы.
Без использования блока try
… finally
, если какой-либо код, изменяющий активы, вызывает ошибку, это может предотвратить вызов StopAssetEditing
. Чтобы избежать этой ситуации, заключайте вызовы в блок try
…finally
с StartAssetEditing
, а код модификации вашего объекта — в блоке try
, а вызов StopAssetEditing
— в блоке наконец
блок. Это гарантирует, что если во время внесения изменений в блок try
произойдут какие-либо исключения, по-прежнему гарантируется, что AssetDatabase.StopAssetEditing
будет звонил.