Detecting enemies - SphereCast or Sphere Collider?

I want to be able to detect enemies within a certain range of my player. To do this, I want to build a hash table of known enemies within range of my player and cast rays to see if they are visible or not.

In order to see any enemies are in range of the player, I have two options:

1) Attach a sphere collider to my player, set it to "trigger" and add any enemies who fall into the trigger to my hash table. So far, the results for this seem variable and I'm getting trigger events when other triggers enter the sphere which is undesirable... I only want to listen for colliders.

2) Use Physics.SphereCast at a set interval. This will likely be more accurate.

Considering my scene could have up to about 20 players at a time all checking for enemies, which of the two methods would be considered the most sensible?

In such cases i would recommend Physics.OverlapSphere which gives you an array of all colliders within the sphere radius. Note that you can use a seperate layer for your enemies and specify a layermask when you use OverlapSphere. That way you only get colliders that are on this layer. For the visibility check it seems that you can't get around a raycast. For that purpose i'd like to mention Collider.Raycast which tests only against this collider.

SphereCast is like raycasting, but instead of casting a single ray it casts a sphere. So this would be more useful for, say, detecting if a thick beam hits something, or if a ball will hit anything as it moves along the direction of the ray.

The sphere collider seems more suited to your task as described, and may be less expensive to check. You will have to skip over collisions with objects you aren't interested in; you can script that, or use Unity's collision layers.

If your player is moving fast enough that it will skip completely over obstacles between frames, then maybe SphereCast is indeed the way to go. You'd be casting between the player's position last frame to the position this frame, and using the distance argument as well. You'd be able to limit the collisions to objects of interest using the layermask argument.

I think a trigger sphere would be less heavy for the machine. And if it also fires when other triggers enter, just check if it's a collider. But instead, could you not use isVisible?