Unity C#-具有LayerMask的Physics.Raycast方法似乎并未忽略给定的层

时间:2019-08-09 12:09:36

标签: c# unity3d raycasting

您好,我在射线投射时使用了图层蒙版,但是无论我做什么,都不会忽略给定的图层。 我在&正常之前使用了这种方法。猜猜有一个我无法解决的问题。 这是我使用方法的方式:

    // 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 }

我知道此方法有16种重载,但我确定我的方法是正确的。

据我所知,这个符号(〜)使它忽略了给定的层。我也尝试将其删除,结果是一样的。

我也尝试发送0作为图层蒙版,这意味着忽略所有图层,在这种情况下,射线与预期的东西没有碰撞 。 任何建议表示感谢。

2 个答案:

答案 0 :(得分:1)

知道了。 这是我的预制件:

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

父层应被忽略,子层与射线碰撞。

但是 hit.transform.gameObject.layer 将返回包含坚硬物体的游戏对象的游戏层 。这是ParentGameObject。紧随对撞机的游戏对象是哪一层都没关系。

对于该解决方案,我向ChildGameObject添加了刚体,它现在可以工作。

答案 1 :(得分:0)

如果对图层蒙版进行抽象,则更容易理解和处理。

例如,如果要获取特定图层的遮罩:

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

或者,如果您要排除特定的图层,则:

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

这是主要的实用程序类:

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);
    }
}