What is the best way to detect objects in radius every frame?

Hi everyone,

I’m working on (in essence) a character senses script for my NPCs and Enemies. How I plan to do this is either use a collider’s on OnColliderEnter function or Physics.SphereOverlap, with radius adjusted for the sight range float and character’s FOV. I wanted to ask whether one is more performant than the other because ideally, the array of the objects in the range would have to be updated every frame.

The reason I can’t just have the NPCs store an array of the interactibles is that I plan for there to be hundreds of these interactives in a scene and some more will also spawn mid-game so it would be awkward to update every NPCs arrays.

Also if anyone has any better ideas please do share, I’m open to changing how I go about this system :slight_smile:

Thank you

I would go with OverlapSphere but I think only the Profiler can answer this definitively for your game. However, a few principles:

OverlapSphere is pretty efficient and better than OverlapCapsule, which is better than OverlapBox then ConvexMesh then ConcaveMesh. Much different? Probably not a lot.

You really don’t need to run it every frame. Use InvokeRepeating or a Coroutine timer to run it every 10 frames, say. Could be different for bullets but for NPCs, every frame is generally not required.

Standard OverlapSphere can generate a lot of garbage because the number of results might change every time, meaning different size arrays. Garbage Collection could be your biggest problem and, once again, I’d have to refer you to the Profiler to find out if that was the case. An alternative is OverlapSphereNonAlloc but you’d have to create your own results buffer of an appropriate size.

Sort out your physics layers and static GameObjects. Many of my students ignore this but it can make a big difference in very dense environments.

Don’t try and code around the topic using ifs and loops. Single statement solutions are always best for reasons of cache hits and pipelines and so on. I’ve seen code that was well meaning but badly performant. Trust the Unity and .Net people to write efficient code behind their SIMD instructions.

Finally - and sorry to keep going on about this - but don’t try and guess where the performance problems will be. Write the code using good SOLID principles and, if the Profiler or testing tells you there’s a problem, it should be easy to plug in an alternative.