Struggling To Understand Raycast Layers

Hi Guys,

I’m trying to do a raycast to see if I’ve hit an object. I’m using this code here:

    public IEnumerator TrainingBinocularControl()
    {
        GameObject cam = GameObject.Find("BinocularViewCamera");
        GameObject finger = GameObject.Find("TheFinger");
        LayerMask mask = GetComponent<GridReference>().layerMask;
        bool bHit = false;
        RaycastHit hit;

        while (!bHit)
        {
            if (Physics.SphereCast(cam.transform.position, 10, cam.transform.forward, out hit, mask))
            {
                if(hit.transform.gameObject.tag == "Target")
                {
                    bHit = true;
                    yield return null;
                }
                else
                {
                    Debug.DrawRay(cam.transform.position, cam.transform.forward);
                    Debug.Log("TRY ME: " + hit.transform.gameObject);
                    // get outta here.. nothing to see here
                }
            }

            yield return new WaitForFixedUpdate();
        }

The issue is the layerMask is not working correctly.

I have 2 objects: The target, and the terrain. I’ve created two new layers in the layers panel: Target and Terrain. I’ve assigned the terrain to the Terrain layer in the inspector, and the target to the Target layer in the inspector. In the inspector I also change the layerMask and press play. With different results. These are what I get:

layerMask: Default, Target = “TRY ME: Terrain (UnityEngine.GameObject)”
layerMask: Target = “TRY ME: Terrain (UnityEngine.GameObject)”
layerMask: Terrain = “TRY ME: Terrain (UnityEngine.GameObject)”
layerMask: Everything = N/A - Nothing returns?
layerMask: Nothing = Nothing Returns (no duh there)

This is making no sense to me. All I want is for the terrain to be excluded from the Raycast. Can anyone explain?

This is the code for how you raycast, but the important bit about how you create your LayerMask isn’t here, so it’s going to be a little hard to debug. If you want to target a specific layer in code, use “1 << layerNumber”, where you can get the layer number using the LayerMask.NameToLayer(“layerName”).

What that does is it takes the integer “1” and shifts it left by that many spaces, so if “terrain” were layer 5, it would shift it 5 spaces to the left, making it 100000. It’s a bit mask, so each space in that integer is a binary number, 0 or 1, indicating if the layer corresponding to that spot should be included or not.

you need to include a distance in the raycast if you want to use the variant with hit and mask…

it’s because the distance and mask are both optional parameters, and they are both numbers. You are providing the mask as the fifth parameter which is being implicitly converted and used as the distance… you can’t skip an optional parameter and provide a value for another one later in the parameter list.

1 Like

Lol… Thanks Lefty

:smile: it got me too

1 Like

Great catch!