﻿# V4008\. Unity Engine\. Avoid using memory allocation Physics APIs in performance\-sensitive context\.

Анализатор обнаружил в часто выполняемом коде использование аллоцирующих память методов Physics\.RaycastAll, Physics2D\.OverlapSphere или подобных им\. 

Такие методы создают массив при каждом вызове, что может снизить производительность\. Вместо них стоит использовать неаллоцирующие вариации методов, в которые можно передать предварительно выделенный массив\.

Рассмотрим пример:

```cpp
public class HitScript : MonoBehaviour
{
  void Update()
  {
    AllocMethod();
  }

  void AllocMethod()
  {
    RaycastHit[] hitsTargets = Physics.RaycastAll(transform.position, 
                                                  transform.forward);

    foreach (RaycastHit hit in hitsTargets)
    {
      if (hit.collider.gameObject.name != "PlayerAdvanced")
      {
        ....
      }
    }
  }
}
```

`Update` будет каждый кадр вызывать `AllocMethod`, использующий аллоцирующий метод `RaycastAll`\. Из\-за постоянного создания новых массивов, которые содержат попадания луча, производительность ухудшится\.

Данный код можно оптимизировать\. Для этого нужно заменить метод `RaycastAll` на неаллоцирующий метод `RaycastNonAlloc` и использовать его вместе с предварительно выделенным массивом\.

Вариант оптимальной реализации: 

```cpp
public class HitScript : MonoBehaviour
{
  void Update()
  {
    NonAllocMethod();
  }

  const int MAX_RAYCAST_HIT_COUNT = 10;
  RaycastHit[] _hitsTargets = new RaycastHit[MAX_RAYCAST_HIT_COUNT];

  void NonAllocMethod()
  {
    int countOfResults = Physics.RaycastNonAlloc(new Ray(transform.position,
                                                         transform.forward ),
                                                 _hitsTargets);

    for(int i = 0; i < countOfResults; i++)
    {
      if (_hitsTargets[i].collider.gameObject.name != "PlayerAdvanced")
      {
        ....
      }
    }
  }
}
```

Для использования `RaycastNonAlloc` заранее создан вспомогательный массив `_hitsTargets`\. Максимальное количество попаданий луча ограничено размером этого массива\. После вызова метода `RaycastNonAlloc` количество попаданий луча будет записано в переменную `countOfResults`, а сами попадания будут записаны в массив `_hitsTargets`\. Таким образом, в каждом кадре будет использоваться массив `_hitsTargets`, под который память выделяется лишь один раз\.

На момент написания документации к диагностике в классе `Physics2D` все методы с припиской "NonAlloc" помечены как устаревшие, им на замену можно использовать неаллоцирующие перегрузки обычных методов\. Например, вместо `Physics2D.BoxCastAll` стоит использовать перегрузку `Physics2D.BoxCast`, принимающую массив для получения всех попаданий\.