- Home /
Spherecast for ground check glitch
Hi there.
I have a character controller which is have a rigidbody (use gravity, non-kinematic) and a capsule collider (non-trigger, height = 1.8, center = 0.9).
I use the following code to detect if the character is on the ground:
private bool GroundCheck (float groundCheckHeight, out bool result)
{
Physics.SphereCast (this.transform.position + Vector3.up * CharCollider.radius,
CharCollider.radius, Vector3.down, out groundHitInfo,
groundCheckHeight, LayersHelper.LayerExceptEnemiesPlayerAndUI,
QueryTriggerInteraction.Ignore);
Debug.Log ("Dist: " + groundHitInfo.distance + ", collider: " + groundHitInfo.collider);
return result =
groundHitInfo.distance <= groundCheckHeight
? true : false;
}
LayersHelper
is just a class which contains constants for layers.LayerExceptEnemiesplayerAndUI = ~(1 << 10) | (1 << 5) | (1 << 8)
With this code I'm getting result twiching from true
and debug prints that collider is a Terrain
, if I move the character or even turn the camera, result swithes to false
and collider in debug is empty.
If I use Physics.AllLayers
then result is always true
.
If I use ~(1 << 10)
(layer 10 is a Player
layer and character (with all children is set to this layer) the result is still always true
even if I jump, and again collider is empty.
And no matter what check distance, is it 0.1f, 0.001f, 0.3f, the result still that unadequate.
So, does anyone know what is going on here? How is it possible so collision is happen but there's no colliders?
Answer by Ermiq · Aug 18, 2018 at 06:55 PM
Well, the problem is solved!
For anyone who interested: the thing is, Unity uses some offset for collision detection. When two colliders intersect each other, Unity detects if they went inside each other more than this offset allows. If so, collision detection happens.
You can find this offset in Edit -> Project settings -> Physics
(or Physics2D if you use 2D). It's called Detect Contact Offset
and it's 0.01
by default.
So, to solve my problem, I just substructed this offset off the sphere size:
Physics.SphereCast (this.transform.position +
// here, to make the sphere start position higher by this offset
Vector3.up * (CharCollider.radius + Physics.defaultContactOffset),
// and here to make the sphere radius lower by this offset
CharCollider.radius - Physics.defaultContactOffset,
Vector3.down, out groundHitInfo, maxCheckHeight,
LayersHelper.LayerExceptEnemiesPlayerAndUI, QueryTriggerInteraction.Ignore);
Also, why did RaycastHit return no colliders? Because if there's no collision at the given range, then RaycastHit result has .collider = null; .transform = null; distance = 0;
!
That's all. Now the sphere acts as I expect, collision detection works like a charm.
Happy coding, all!
I tried all kinds of different casts and collisions, and this is what finally worked for me! Thank you so much!
Thank you very much! I wasted so much time looking for this solution and NOT ONE video on Youtube explains this simple thing. I'm sure you have gone ahead and become a great developer. Many thanks once again!
Your answer
Follow this Question
Related Questions
Inconsistent results when doing line/sphere casts? 0 Answers
Checking if grounded using SphereCast -- Acting like Raycast 1 Answer
Why is this raycast working? 2 Answers
The enemy's animation stop and moving of the whole character 0 Answers
How to rotate a player to match the terrain slope? 0 Answers