Bartek Dusza
Bartek Dusza

Reputation: 174

OverlapCircleAll optimization

I've made boids in unity but when trying to render a 1000 of them the performance is really bad, in my update function i use Physics.OverlapCircleAll to check all surroundiing boids. Is there any way to do this more optimized? Here is my update function:

void Update()
    {
        Collider2D[] hitColliders = Physics2D.OverlapCircleAll(Position, radius,layerMask.value);
        List<Boid> boids = hitColliders.Select(o => o.GetComponent<Boid>()).ToList();
        boids.Remove(this);
        Flock(boids.ToArray());
    }

Upvotes: 1

Views: 1618

Answers (1)

chantey
chantey

Reputation: 5847

Absolutely! Physics.OverlapCircleAll creates a lot of garbage every time it is called. What you're looking for is Physics.OverlapCircleNonAlloc, which will not create any garbage as it uses a buffer:

Collider2D[] hitsBuffer = new Collider2D[30]; //limit the amout of possible boid interations

void Update()
{
    int numHits = Physics2D.OverlapCircleNonAlloc(Position, radius, hitsBuffer, layerMask.value);
    Flock(hitsBuffer,numHits);
}

void Flock(Collider2D[] hitsBuffer, int numHits){

    for(int i = 0; i < numHits; i++){
        var boid = hitsBuffer[i].GetComponent<Boid>();
        if(boid == this)
            continue;
        //flocking algorith here
    }
}

Note how in the above code no additional arrays are created each frame, which is quite expensive. To check how much time is being spent where check out the Profiler:

  • Orange is 'Physics', working out the overlaps
  • Cyan is 'Scripts', calcuations in code, ie the flocking algorithm
  • Dark green is 'GarbageCollector', handling arrays created and destroyed each frame

PS If not already, ensure that the boids are using a CircleCollider2D, this is the easiest for Unity to calculate.

PPS You may want to double check that if(boid == this) actually gets called. I thought that Physics.Overlap... ignores this collider.

Upvotes: 1

Related Questions