Detecting Surrounding GameObjects

Some Background Context:

So I have a 2D prototype in Unity I am working on that has enemy entities that have rigidbody2D component set as dynamic as I am using physics (AddForce()) for movement. I am using physics for movements as I want entities to have a physicsy feeling (slight accel / decel movement, knock back when hit / from explosions, etc.) and Unity physics system with support what I need and I would not really be able to create something myself anyways.

I want my enemies to be able to have knowledge about the entities around it (relatively large area, anywhere from 10 - 25 Unity units radius) and my initial implementation was a quick and simple trigger collider that called a script any time a GameObject in a matching layer entered or exited which worked at first. When I stress tested with a lot of entities in the same area, I noticed the performance when down exponentially with Physics2D.FindNewContacts() taking up a ton of time in the profile. Because the detection collider is on a game object under the enemy entity that has the dynamic rigidbody2D component, each new entities in the area exponentially adds more contacts (when I have 4 entities moving in range of each other that is 4 entities re-calculating contact points for 3 other entities and then I have 30 entities moving in range of each other that is 30 entities re-calculating contact points for 29 other entities and so on).

The only 2 options I can think of are:

• Use a kinematic Rigidbody2D and write custom code for handling "physics" interactions
• Remove the detection collider and do area scanning in a different way.

Option #1 seems like a lot of work especially since I don't really need anything outside of what unity physics support (it is really just the performance which I assume is more just because of how I am doing things) so I am thinking of how to handle Option #2.

What I am thinking of doing at a high level is:

• Remove the detection collider
• Add a queue for a detection area scanning (for lack of a better term) that game objects can add themselves to or remove themselves from
• I can process this queue in a co-routine or something (it does not need to check every frame for every entity that need detection scanning) so that each frame I do a scan for X entities
• This detection scanner would call something like Physics2D.CircleCastAll() and then process those hits (in the same way the detection script did when using the collider).

For content, this scanning is mainly for AI purposes. Right now it is just for enemies to be able to track the player when in range however it will be expanded upon later (like enemies keep track of nearby enemies to heal if possible as one example).

Does this seem like a sane way to handle this kind of problem? Is there "standard" way of handling something like this? Am I missing something with the core problem that could solve this issue easier?

I'm thinking of giving the detection method to the player and not the enemy.So instead of allowing 30 enemies to always detect 1 player, I'm thinking of letting one player find 30 enemies that are close to him and call a function to have the enemy chase them depending on the distance from the enemy to the player, i think of using:

void EnemyDetection()
{
AttractedEnemy = Physics2D.OverlapCircleAll(playerTransform.position, effectionRadius, EnemyLayer).ToList();// can be optimized
}

and the use for loop to call nemy function

void AttractEnemy()
{
for (int i = 0; i < AttractedEnemy.Count; i++)
{
AttractedEnemy[i].GetComponent<Attractable>().Attract(transform.position);
}
}

And then in Attractable script in enemy, use Attract function:

$$`$$