What's the reasoning behind Raycasts hitting disabled colliders?

I was noticing some weird behavior in my game, where some “hidden” objects were getting detected by my player’s “interactable object” system. After debugging it, I found that calls to SphereCastNonAlloc were hitting colliders that were currently disabled. Here’s the code I’m using, and in this case, it’s just an test where I Debug.Log whether the collider is enabled or disabled:

var hitCount = Physics.SphereCastNonAlloc(origin: Head.position,
    radius: GameSettingsDirector.Instance.GeneralSettings.PlayerActivationSpherecastRadius,
    direction: Head.forward,
    results: _interactableTargetHits,
    maxDistance: sphereCastDistance,
    layerMask: LayerUtil.InteractableMask);

if (hitCount > 0)
{
    //Debug.Log($"Primary hits: {hitCount}");
    for (var hitIndex = 0; hitIndex < hitCount; hitIndex++)
    {
        var raycastHit = _interactableTargetHits[hitIndex];
        Debug.Log($"Hit {raycastHit.collider.gameObject.name}. Enabled? {raycastHit.collider.enabled}");
    }
}

This code ends up hitting colliders that have been disabled, such as this one:

6470009--726119--upload_2020-10-29_10-59-30.png

I was wondering if anyone knows the reasoning as to why raycasts hit disable colliders? If I completely turn off the GameObject (SetActive(false) on the gameobject) it stops the raycasting, but simply setting the collider to disabled does not. I can always check whether the collider is disabled via code, but it just seems like something would have expected the raycasting system to have done.

1 Like

I think this issue has been around for a long time, it seems that the easiest solution is to move the collider object to layer “Ignore Raycast” when you disable the collider and back to the original layer when you re-enable. I agree that it seems counter-intuitive, but I guess it does give you an additional level of control over your object interaction. For example, you may want to disable physics interactions, but still want to raycast to the object to confirm LOS.

2 Likes

I guess it does add some functionality, at the expense of being confusing, so that’s an interesting tradeoff. If the goal was to decouple physics collisions from raycast collisions, I wonder why they didn’t use the same approach as the control over whether raycasts his triggers: There’s a project-wide setting to control that, which you can override on a per-raycast basis. This “disabled collider” use case feels like a similar situation, where control of this behavior should have been explicit, rather than the non-intuitive current implentation.

Anyway, as to the workaround (changing the object’s layer when disabling the collider), that’s probably fine, but that’s the sort of thing I’d generally try to avoid due to the risk of forgetting to return the object to the correct layer when reenabling it.

2 Likes