- Home /
Physics2D.Raycast intermittently returning null
I am currently testing to see if the raycast from an AI hits the player. I'm triggering the cast using OnTriggerStay2D. When the other collider is the player object I peform a raycast to see if the AI can actually see them. The test seems to fail when the player is around 90 degrees perpendicular to the AI.
bool checkInSight (Collider2D other, LayerMask mask)
{
// By default the threat is not in sight.
bool rtn = false;
if (threat != null && !threatHealth.dead)
{
Vector3 direction = other.transform.position - tr.position;
float angle = Vector3.Angle(direction, tr.up);
if (angle <= fovAngle)
{
// Send out raycast towards player
RaycastHit2D hit = Physics2D.Raycast(tr.position, direction, fovRadius, mask);
Debug.DrawLine(tr.position, other.transform.position, Color.cyan);
// If the raycast isn't empty and hits the player...
if (hit.collider != null && hit.collider.gameObject == other.gameObject)
{
rtn = true;
}
if (hit.collider != null) Debug.Log("Ray Hit:" + hit.collider.gameObject);
}
}
return rtn;
}
I've debugged the code a bit and everything up to the Physics2D.Raycast call is correct when its failing. Initial impressions of the code probably makes the layer mask seem like a likely culprit, but because I'm getting hits 90% of the time, surely can't be causing it?
What this line reports to you when it fails?
if (hit.collider != null) Debug.Log("Ray Hit:" + hit.collider.gameObject);
Nothing. If the raycast fails then the RaycastHit2D is completely null, so I get no print out.
Sorry, the hit collider is null, not the hit. The hit is completely empty.
Answer by IceBeamGames · May 21, 2015 at 03:05 PM
Solved it!. The problem was the assumption (on my part) that other.transform.position would return the center of the collider, not the centre of the actual root GameObject. I forgot I've offset the collider and have the center point of the object at the player's feet.
Here is the fix:
bool checkInSight (Collider2D other, LayerMask mask)
{
// By default the threat is not in sight.
bool rtn = false;
if (threat != null && !threatHealth.dead)
{
// Get collider local offset position and rotate it
Vector3 direction = other.transform.rotation * other.offset;
// Add to transform position and then minus current position to get direction
direction = (other.transform.position + direction) - tr.position;
float angle = Vector3.Angle(direction, tr.up);
if (angle <= fovAngle)
{
// Send out raycast towards player
RaycastHit2D hit = Physics2D.Raycast(tr.position, direction, fovRadius, mask);
// RaycastHit2D [] hit = Physics2D.RaycastAll(tr.position, direction, fovRadius, mask);
debugRays.Add(new DebugRay(tr.position, direction, Color.cyan));
// If the raycast isn't empty and hits the player...
if (hit.collider != null && hit.collider.gameObject == other.gameObject)
{
rtn = true;
}
if (hit.collider != null) Debug.Log("Ray Hit:" + hit.collider.gameObject);
}
}
return rtn;
}
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Calling a function from another script on Raycast2D 1 Answer
Check if Object is in a Position? (Using Compare tag) 1 Answer
RaycastHit2D does not work? 0 Answers