Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
menu mobile close menu
Проверка проектов
Дополнительная информация
toggle menu Оглавление

V4007. Unity Engine. Avoid creating and destroying UnityEngine objects in performance-sensitive context. Consider activating and deactivating them instead.

25 Ноя 2024

Анализатор обнаружил создание Unity-объекта в часто выполняемом методе.

Регулярное создание/уничтожение игровых объектов не только нагружает центральный процессор, но и приводит к увеличению частоты вызовов сборщика мусора. Это негативно отражается на производительности.

Рассмотрим синтетический пример:

CustomObject _instance;

void Update()
{
  if (....)
  {
     CreateCustomObject();
     ....
  }
  else if (....)
  {
    ....
    Destroy(_instance.gameObject); // <=
  }
}

void CreateCustomObject()
{
  var go = new GameObject();       // <=
  _instance = go.AddComponent<CustomObject>();
  ....
}

Здесь в методе 'Update' создаётся и уничтожается некоторый игровой объект '_instance'. Т. к. 'Update' выполняется при каждом обновлении кадров, по возможности рекомендуется избегать в нём этих операций.

Данный код можно оптимизировать. Для этого нужно один раз инициализировать '_instance', например, в методе 'Start', после чего в методе 'Update' использовать метод '_instance.gameObject.SetActive' для включения/отключения объекта вместо создания/уничтожения.

Пример реализации:

CustomObject _instance;

void Start()
{
   CreateCustomObject();
   _instance.gameObject.SetActive(false);
   ....
}

void Update()
{
  if (....)
  {
    ....
    _instance.gameObject.SetActive(true);
  }
  else if (....)
  {
    ....
    _instance.gameObject.SetActive(false);
  }
}

void CreateCustomObject()
{
  var go = new GameObject();       
  _instance = go.AddComponent<CustomObject>();
  ....
}

Такая же оптимизация актуальна и для компонентов 'MonoBehaviour'. В этом случае следует использовать свойство 'enabled' компонента для его включения/отключения.

Нередко требуется создавать/уничтожать множество временных объектов, например, снарядов. Такие случаи также можно оптимизировать заменой указанных выше операций на включение/отключение, но с применением пулов. Для таких случаев Unity предоставляет готовый набор универсальных пулов, находящихся в пространстве имён 'UnityEngine.Pool', например, 'ObjectPool<T>'. Подробности о принципе работы с этим классом можно найти на сайте Unity: тут или тут.