To chceck if a player is grounded i use this function:
public bool RecalculateGroundiness(out RaycastHit? leastAngle)
{
leastAngle = null;
RaycastHit[] hits = Physics.SphereCastAll(transform.position, radius, Vector3.down, 0f);
foreach (RaycastHit hit in hits)
{
if (hit.collider.gameObject == transform.parent.gameObject) continue;
Debug.Log(hit.normal + " " + hit.collider.name);
if (IsFloor(hit.normal))
{
if (!leastAngle.HasValue) leastAngle = hit;
else if (GetAngle(hit.normal) < GetAngle(leastAngle.Value.normal)) leastAngle = hit;
}
}
return leastAngle.HasValue;
}
And the problem is, whenever i touch something (i mean, the ground check touches) it just classifies the collider as ground. The Debug.Log always shows (0, 1, 0). It’s worth saying that, the ground check is inside the player and the sphere cast expands only 0.01 units beyond the player collider.
I see that you are setting the distance of your SphereCastAll to 0. I’ll assume from this that when you are touching the ground, this sphere is already overlapping the ground. Here is what the documentation says about colliders that are already overlapping with the sphere at the start of the cast:
Notes: For colliders that overlap the sphere at the start of the sweep, RaycastHit.normal is set opposite to the direction of the sweep, RaycastHit.distance is set to zero, and the zero vector gets returned in RaycastHit.point. You might want to check whether this is the case in your particular query and perform additional queries to refine the result.
(From the below page)
This makes sense because the normal is undefined if the sphere is overlapping another collider; what point would you consider to be the collision point in that case? You could possibly start the cast some distance above transform.position and use a non-zero maxDistance in the SphereCastAll function call.
If your current SphereCastAll code at least gets you the correct collider, maybe you could use the Collider.ClosestPoint function to estimate where the collision occurred and then cast a ray at the point to get the normal.
Hard to know without seeing your scene and more debugging, seems like you need the normal of what your player is stepping on, I’m assuming it’s for some inverse kinematics of the foot, if so instead of casting a sphere I would cast 4 rays pointing downwards, the 4 points would be forming a square, I would then calculate the distance between each point and the point of impact of those rays, and use those 4 distances to create 2 vectors, one for each leg and use those for the IK.