Inconsistent Reflection/Ricochet of 2D Lines at Specific Angles via Raycasting and 2D Colliders

Hello!

I am currently implementing a rotating beam weapon for a 2D game which reflects/ricochets from its original point of contact with a 2D collider and continues until hitting another 2d collider.

Using the initial 2D raycast hit to begin another raycast with its direction obtained via reflection I have only had success when the direction of the initial raycast hits colliders at specific angles.

I’ve hit a roadblock finding an explanation for this behaviour, and would appreciate any insight into what is causing it and how it can be fixed.

My code is below, and here is a video of the problem in action.

public class Laser : MonoBehaviour
{

    public Transform laserHit; // point where laser initially hits
    public Transform laserRicochetHit; // point where laser ricochet hits

    private LineRenderer lr;


	void Awake ()
    {
        lr = GetComponent<LineRenderer>();
        lr.enabled = true;
        lr.useWorldSpace = true; // world origin instead of the parent object origin
        lr.numPositions = 3; // 0 - origin, 1 - initial wall hit, 2 - ricochet hit
    }


    void Update()
    {
        RaycastHit2D hit = Physics2D.Raycast(transform.position, transform.parent.up);
        laserHit.position = hit.point;

        // create a ricochet line via raycasting
        Vector2 ricoDir = Vector2.Reflect(transform.parent.up, hit.normal); // direction for ricochet raycast
        RaycastHit2D ricochetHit = Physics2D.Raycast(hit.point, ricoDir);
        laserRicochetHit.position = ricochetHit.point;

        // set line positions
        lr.SetPosition(0, transform.position); // origin
        lr.SetPosition(1, laserHit.position); // initial wall hit
        lr.SetPosition(2, laserRicochetHit.position); // ricochet hit

        // draw debug lines
        Debug.DrawLine(transform.position, hit.point);
        Debug.DrawLine(hit.point, ricochetHit.point);
    }
}

I am new to Unity and C#, and would appreciate any and all comments. Thanks!

That code looks good, especially for a beginner. Can you post a screenshot of the scene view? What is the raycast shooting at? Are there colliders on the edges of the screen?

2 Answers

2

From the documentation for raycast:

Additionally, this will also detect
Collider(s) at the start of the ray.
In this case the ray is starting
inside the Collider and doesn’t
intersect the Collider surface. This
means that the collision normal cannot
be calculated in which case the
collision normal returned is set to
the inverse of the ray vector being
tested. This can easily be detected
because such results are always at a
RaycastHit2D fraction of zero.

So, what you probably need to do, is get the initial ray start point out of your starting collider. Try disabling the collider on the cube to confirm this is the problem.

No problems with the initial raycast exiting the cube which emitting the beam. This does explain the issue though. It appears the initial hit position is landing within the wall's collider when approaching from most directions. Therefore, my ricochet raycasts are unable to obtain the correct normal and go nowhere. Thanks for this, I'll read the documentation more closely next time. With this information I have a leg up on finding a solution, but would be welcome to anyone else's solutions of course! I'll post my own provided I'm able to come up with one myself.

The answer above is really useful but more specifically to solve this you need to modify the hit normal you are giving to the Reflect- all I did was create a new variable for the hitnormal I gave the Reflect by adding the hitnormal + hitpoint- now it works as it should.