- Home /
RaycastHit2D never contains a collider
I am trying to detect if a user is grounded. I have a GameObject
on the screen with a BoxCollider2D
component on it and is on the Ground
Layer. I then have a character with a Rigidbody2D
and CircleCollider2D
on it along with this class:
public class CharacterEnvironment : MonoBehaviour {
float distToGround;
// Use this for initialization
void Start() {
var collider = GetComponent<CircleCollider2D>();
distToGround = collider.bounds.extents.y;
}
// Update is called once per frame
void Update() {
RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.down, distToGround + 0.1f, LayerMask.NameToLayer("Ground"));
Debug.Log(hit.collider);
if (hit && hit.collider != null) {
Debug.Log(hit.collider);
}
}
}
When my raycast runs, hit.collider
is always null
, even when the object is resting on top of the Ground Object. Am I doing the calculations wrong?
Answer by Commoble · Apr 02, 2017 at 07:55 PM
Your problem: The last argument in a physics cast is supposed to be a layer mask; however, LayerMask.NameToLayer returns a layer index, not a layer mask. A layer index is the ID of the layer in the Tags and Layers window; a layer mask is represented by a 32-bit value where each binary digit is a 1 if the mask includes that layer, and a 0 if it does not (where layer index 0 is the least-significant bit).
To illustrate the difference:
A layer mask containing only layer index 0 has the value
00000000000000000000000000000001
A layer mask containing only layer index 5 has the value
00000000000000000000000000010000
A layer mask containing layer indices 6, 7, and 9 has the value
00000000000000000000000101100000
You could use bitshifting to convert a layer index to a layer mask containing only that layer, but a simpler solution is to declare a public LayerMask groundLayer;
field in your script and define your ground layermask in the inspector (which has a reasonable layermask editor). You can then use this layermask in your raycasts. This is also more efficient than using a string to find your layer.
Answer by eatsleepindie · Mar 31, 2017 at 10:53 PM
You may need to start your raycast a bit up from the transform's position so that it is not starting at the same point where the player contacts the ground.
RaycastHit2D hit = Physics2D.Raycast(transform.position + Vector2.up * 0.1f, Vector2.down, distToGround + 0.2f, LayerMask.NameToLayer("Ground"));
If that doesn't work you can always toss a Debug.DrawRay() into your update so you can visualize the ray via the Scene window.
Debug.DrawRay(transform.position, Vector3.down * (distToGround + 0.1f), Color.red);
This doesn't do anything, and the raycast draws out the way I was expecting, and the cast overlaps the "Ground" layer.