Evren Ozturk
Evren Ozturk

Reputation: 928

Unity C# - Physics.Raycast method with a LayerMask doesn't seem to ignore given layers

Hello i'm using a layer mask while ray casting but whatever i do it doesn't ignore the given layer. I used this method before & was working fine. Guess there is a problem that a i cannot resolve. Here is how i use the method:

    // Ignore layers 21 & 0
    int layerMask = ~LayerMask.GetMask(LayerMask.LayerToName(21), LayerMask.LayerToName(0));
    if (Physics.Raycast(position, direction, out hit, maxDistance, layerMask)) {
        // Always reaching this point where hit.transform.gameObject.layer = 21
        if (XLayers.shouldDoStuff(hit.transform.gameObject.layer)) {
          // DO stuff
       } else{ // other stuff }
    } else { some other stuff }

I know there 16 overloads of this method but i'm sure mine is the correct one.

As far as i know this symbol ( ~ ) makes it ignore the given layers. I tried to remove it too the result is the same.

Also i tried to send 0 as the layer mask which means ignore all layers, i this case the ray collides with nothing as expected . Any advice appreciated thanks.

Upvotes: 1

Views: 1884

Answers (2)

Iggy
Iggy

Reputation: 4888

It's much easier to understand and deal with layer masks if you abstract it.

As an example, if you want to get a mask for specific layers:

LayerMask mask = LayerUtility.Only("Player", "Friends");

Or if you want to exclude specific layers:

LayerMask mask = LayerUtility.AllBut("Enemies", "Obstacles");

Here is the main utility class:

public static class LayerUtility
{
    public static LayerMask Only(params string[] ids)
    {
        LayerMask mask = new LayerMask();

        for (int i = 0; i < ids.Length; i++)
        {
            mask = Add(mask, Shift(Get(ids[i])));
        }

        return mask;
    }

    public static LayerMask AllBut(params string[] ids)
    {
        return Invert(Only(ids));
    }

    public static LayerMask Invert(LayerMask mask)
    {
        return ~mask;
    }

    public static LayerMask Add(LayerMask mask1, LayerMask mask2)
    {
        return mask1 | mask2;
    }

    public static LayerMask Shift(LayerMask mask)
    {
        return 1 << mask;
    }

    public static LayerMask Get(string id)
    {
        return LayerMask.NameToLayer(id);
    }
}

Upvotes: 0

Evren Ozturk
Evren Ozturk

Reputation: 928

Got it. This is my prefab:

ParentGameObject ( Layer : 21, has rigidBody, has collider )
    ChildGameObject ( Layer : 18, no ridigBody, has collider )

The parent layer is ignored as it should be & the child is collided with the ray.

BUT hit.transform.gameObject.layer returns you the layer of the gameObject that CONTAINS THE RIGIDBODY. Which is the ParentGameObject. Doesn't matter what layer is the game object contaning the collider.

For the solution I added a rigidbody to the ChildGameObject it works now.

Upvotes: 2

Related Questions