I have a solution that should work even for detailed bodies like a sphere.
In my game, the player is a sphere. I want that sphere to be able to jump even when the center of the sphere is not in contact with the ground (say, if the ball rests in a hole).
Raycasting will not work, even when using a cone, in instances when this hole is larger than the cone.
The strategy is: create a collider without a mesh renderer, and make that collider a trigger. Then, on contact with the desired types of objects (in my case, I have a layer for “groundable” objects), have that invisible collider raise a “grounded” flag on OnTriggerEnter and lower it on OnTriggerExit.
Make the collider’s position the same as the object, minus a small y offset. In my case, I also diminish the radius of the collider to make sure it only sticks out from the very bottom. A custom mesh collider could be resized in the X/Z axis for similar results.
This effectively ensures that all collisions with the ground are only detected downward from the player since the hit box is only exposed under the object; all other collisions will be protected by the “solid” body of the player.
This technique is the most responsive for me. Just be careful that the collider does not rotate with the ball, though, or else jumping won’t work when the ball is facing up.
@aldo - 3,000+ views on this question in two weeks! Strange isn't it? It's impossible to guess what will be wildly popular!! happy new year!
– Flocculus