How would you implement a "Near Miss" feature?

I am trying to implement a “near miss” feature for bonus points in my game. One problem I have is that I am already using colliders on the gameobject to watch for collisions.

How could I implement this feature?

Would you recommend using another set of colliders on a child gameobject which are slightly larger, to trigger a near miss, or would you suggest calculating distances manually?

The easiest way is to add a second collider to your object that is slightly bigger than the actual collider. Make sure the collider is set marked as trigger so it won’t mess up physics. To detect a near miss you would simply use the OnTriggerExit callback to see if the object you “touched” is your target.

Depending on what actually happens when you hit the target you might need to set a flag when you detected a hit to prevent a near miss detection after an actual hit.

If you use “fast bullets” physics is usually too imprecise. In such cases you usually use an additional raycast along the movement path. Here we can’t use Triggers. Instead we use an additional SphereCastAll to get all potential near misses as we travel along the path. Those objects should be added to a List but you have to take care of duplicates. A Dictionary might be a simple solution.

All you have to do is check for each object in that list if you already have passed it. You do that by creating a vector from your bullet to that object and calculate the dot product with your bullet’s forward vector. If the value is negative you have passed the object.

If we passed an object we can remove it from our List / Dictionary. Next we have to check how close the bullet actually were. Since the bullet moves fast it’s possible that it’s already far beyond the target, so a simply distance check won’t help here. What you want to calculate is the distance of the object to your line of movement. This is quite easy since Unity provides Vector3.Project. To get the closest distance of the target to your movement line you simply do this:

// C#
// for each "target" in our list we do:
Vector3 dir = target.position - transform.position;
// have we passed the target?
if (Vector3.Dot(dir, transform.forward) < 0)
{
    Vector3 v = Vector3.Project(dir, transform.forward);
    Vector3 dist = dir - v;
    if (dist.magnitude < nearMissThreshold)
    {
        // we have a near miss
    }
    // remove "target" from our list
}

This assumes that this script is attached to the bullet and transform.forward is the movement direction of the bullet. “target” is the Transform component of the current “potential near-miss object”.

If distance between some vectors is less than some value its a near miss.
Using Vector3.Distance() in fixedupdate is an option. While this scenario would be relatively easy, its unnecessary calculations if dynamic objects will be linear at the time (or for short time) of the event.

I mean, if the projectile moves extremely fast, the near miss chance could be calculated on the start, without every frame or fixed update.