Search code examples
c#unity-game-enginecollision-detectionraycasting

Unity RaycastHit2D with something specific


I have a laser. its goes on forever. But when the laser touches ANYTHING like (wall, player, box, trigger colliders, etc...) it stops there. So it basically doesnt go through colliders.

But I dont want that. I want the laser to ONLY stop if the RaycastHit2D hits a wall. Is there a way to do that? thanks in advance :D

Here's the code:

private LineRenderer lineRenderer;
public Transform LaserHit;
public Transform LaserSpawn;

void Start()
{
    lineRenderer = GetComponent<LineRenderer>();
    lineRenderer.useWorldSpace = true;
}

void Update()
{
    RaycastHit2D hit = Physics2D.Raycast(transform.position, transform.up);
    LaserHit.position = hit.point;
    lineRenderer.SetPosition(0, transform.position);
    lineRenderer.SetPosition(1, LaserHit.position);
}

Solution

  • :EDIT:

    tl;dr - when you call LayerMask.NameToLayer() or anything else, you're getting the layer, which is telling you which bit corresponds to your layer. If you actually want to mask with that layer, then you need to set that bit by bit shifting. That is, if you want to raycast against only walls, then you need to get the walls layer:

    int wallsLayer = LayerMask.NameToLayer("Walls");
    

    and then you need to BIT SHIFT by that amount:

    int wallsMask = 1<<wallsLayer;
    

    Using this with the raycast command will now only return the interactions with walls. If you want to interact with everything EXCEPT walls, then you need to invert the MASK and not the LAYER:

    int everythingButWalls = ~wallsMask;
    

    Using this will now hit anything except a wall (assuming you've actually set the layer - remember that expanding the Layer options and adding a Layer does not actually SET the layer for the GameObject!)


    Create a Layer for walls by going to any GameObject and, under its name, expand the "Layer" box then go to "Add Layer" and name it "Walls" or something.

    enter image description here

    Then go to your walls and set the Layer for each wall to the "Walls" layer you created.

    enter image description here

    Then when you raycast, use the Walls layer as the layer mask:

    void Update()
    {
        int wallsLayer = LayerMask.GetMask("Walls");
        int layerMask = 1<<wallsLayer;
        RaycastHit2D hit = Physics2D.Raycast(transform.position, transform.up, Mathf.Infinity, layerMask);
        LaserHit.position = hit.point;
        lineRenderer.SetPosition(0, transform.position);
        lineRenderer.SetPosition(1, LaserHit.position);
    }