- Home /
Physics2D.Raycast is fine, I'm an idiot
Currently trying to get a ground hit detection system working with Raycast(). This is my current progress:
public bool isGrounded {
get{
LayerMask mask = (1 << LayerMask.NameToLayer ("Terrain"));
RaycastHit2D hit = Physics2D.Raycast (transform.position, Vector3.down, 2, mask);
Debug.DrawRay (transform.position, Vector3.down, Color.green);
// If RaycastHit2D.collider is not Null
if (hit.collider != null) {
Debug.Log ("Raycast Collider not Null");
// Check max grounded distance
if (Vector2.Distance (hit.point, transform.position) < 0.5f) {
Debug.Log ("Raycast Collider Tag: " + hit.collider.tag);
// Return whether the hit collider is a Platform or not
return hit.collider.CompareTag ("Platform");
}
// Player is not grounded, return false.
else {
Debug.Log ("Player is not Grounded");
return false;
}
} else {
Debug.Log("Collider is Null or Did not hit anything");
return false;
}
}
}
The intended use for this is to be called in one of three locations to check if the player is grounded:
The Player presses Jump
The player has non-0 y velocity and is currently marked as grounded
The player has 0 y velocity and is currently marked as not grounded
Not a fool-proof system, but it should handle most cases while I work on other things. My issue is that the Raycast always returns the player object as being hit despite it being on a layer different from the one specified. And if I switch my Player object to Layer:IgnoreRaycast, the Raycast hits nothing despite there being a large Edge Collider 2D below my character. I've tried substituting it with a box collider as well and it still isn't seen by the Raycast(). All of my platforms are marked as Layer:Terrain, Tag:Platform.
OK, I figured out my issue. Aside from overusing the term Player and getting really confused, I forgot to account for the size offset of the Player's boxcollider2D.
Have you actually added "Terrain" to the Layers list?
NameToLayer searches the Layers list, not the hierarchy or tags.
Yes, I have added "Terrain" to the layers list and set all my platforms to be on that layer. Likewise the Player object is on the "Player" layer.
You could try a RaycastAll, sort the hits by distance, iterate through the array, continue if the hit.collider is the player, and break on the first occurance of a hit terrain.
using System.Linq;
RaycastHit2D[] hits = Physics2D.RaycastAll(ray.origin, ray.direction, 100f, layer$$anonymous$$ask, -$$anonymous$$athf.Infinity, $$anonymous$$athf.Infinity).OrderBy(h=>h.distance).ToArray();
foreach(RaycastHit2D hit in hits) {
if(hit.collider.gameObject != gameObject) {
break;
}
}
Answer by meat5000 · Jul 01, 2015 at 01:00 PM
I would Debug.Log hit.point to see where this false detection is occuring. It might show an inconsistency enough to determine that OP has a forgotten script at work or something to that effect.
Thank you meat5000. Doing that I found that the ray was in fact hitting the platform, the error was in my placement of Log messages and using Player in too many cases.
The actual problem it seems was that somewhere along the line I stopped accounting for the Boxcollider size when checking distance to see if the player was grounded. So it was always too far away. Thanks everyone. I guess I was just missing something simple.I just added
float offset = (GetComponent<BoxCollider2D>().size.y / 2);
and added it to the distance check.
Answer by Dave-Carlile · Jul 01, 2015 at 12:46 PM
LayerMask.NameToLayer returns the layer index. You need to pass a Layer Mask to Raycast
, so use LayerMask.GetMask.
Edit: Upon rereading your code, it looks like you're using the index to create the mask. Seems like that should work too, but try using GetMask to see if that helps.
Have you tried increasing the max ray length?
$$anonymous$$y issue is that the Raycast always returns the player object as being hit despite it being on a layer different from the one specified
This is the key
What's odd is that the raycast isn't supposed to return a hit for a collider if the ray origin is inside that collider.
Your answer

Follow this Question
Related Questions
Bitmask/LayerMask used in raycast not working 2 Answers
How to walk on 2d sphere (planet) 2 Answers
Triying to make a character take knockback in a parabolic motion in 2D. 0 Answers
While Moving Left or Right my character falls more slowly. 2 Answers
Assigning found enemy to target variable 2 Answers