The analyzer has detected that the Physics.RaycastAll
, Physics2D.OverlapSphere
memory allocation methods, or similar methods are used in the frequently executed code.
Such methods create an array on each call, which can negatively affect performance. Instead, use non-allocating variants of methods to which you can pass a pre-allocated array.
Look at the following example:
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")
{
....
}
}
}
}
Each frame, Update
calls AllocMethod
that uses the RaycastAll
allocation method. Due to the constant creation of new arrays containing ray hits, performance will degrade.
This code can be optimized. To do this, replace the RaycastAll
method with the non-allocating RaycastNonAlloc
method and use it together with the pre-allocated array.
An optimal implementation option:
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")
{
....
}
}
}
}
The _hitsTargets
auxiliary array is created in advance to use RaycastNonAlloc
. The maximum number of ray hits is limited by the size of this array. After calling the RaycastNonAlloc
method, the number of ray hits is written to the countOfResults
variable, and the hits are written to the _hitsTargets
array. Thus, each frame will use the _hitsTargets
array, for which memory is allocated only once.
At the time of writing the documentation for this diagnostic rule, all methods in the Physics2D
class with the "NonAlloc" prefix are marked as deprecated and can be replaced by non-allocating overloads of normal methods. For example, instead of Physics2D.BoxCastAll
, use the Physics2D.BoxCast
overload that takes an array to get all the hits.