Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)

Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)_第1张图片

Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)

 

目录

Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)

一、简单介绍

二、layer 层查看与创建

layer 层查

layer 层创建

三、层的设置(手动设置和代码设置)

层的手动设置

层的代码设置

四、LayerMask 的介绍和使用

LayerMask 的介绍

LayerMask 的使用(Main Camera CullingMask)

LayerMask 的使用(Physics.Raycast)

附录:

1、批量获取GameObject 及底下子节点的Layer层

2、批量设置GameObject 及子节点同一个Layer层


 

一、简单介绍

Unity中的一些基础知识点。

本节介绍,在Unity 应用的时候,层和层遮罩的创建和使用。

 

官网:Layers are most commonly used by Cameras to render only a part of the scene, and by Lights to illuminate only parts of the scene. But they can also be used by raycasting to selectively ignore colliders or to create collisions


中文:Layers通常被摄像机用来渲染部分场景,和灯光照射部分场景使用。但是它们也可以用来做射线检测时忽略一些collder或Collision使用

 

Unity中是用int32来表示32个Layer层。int32表示二进制一共有32位(0—31)

在Unity中每个GameObject都有Layer属性,默认的Layer都是Default。在Unity中可编辑的Layer共有24个(8—31层),官方已使用的是0—7层,默认不可编辑!

 

二、layer 层查看与创建

layer 层查

1、任意选择场景中的一个 GameObject 即可查看该 GameObject 所在的层

Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)_第2张图片

 

2、前面的序号是所在层序号

Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)_第3张图片

 

layer 层创建

1、点击 Add Layer...

Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)_第4张图片

 

2、在可以编辑的地方取个一个层名即可

Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)_第5张图片

 

3、你新建的 layer 就会显示在层中

Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)_第6张图片

 

4、前面的序号是所在层序号

Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)_第7张图片

 

三、层的设置(手动设置和代码设置)

层的手动设置

1、选择要设置的 GameObject ,点击即可设置为指定层

Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)_第8张图片

 

2、指定 GameObject 设置为指定层

Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)_第9张图片

 

层的代码设置

// Given a layer name, returns the layer index as defined by either a Builtin or a User Layer in the.

public static int NameToLayer(string layerName);

// Given a layer number, returns the name of the layer as defined in either a Builtin or a User Layer in the.

public static string LayerToName(int layer);

1、Cube 的 Layer Default

Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)_第10张图片

 

2、代码设置 Cube 的 层

Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)_第11张图片

 

3、运行场景,Cube 设置层为 “TestLayer” 或者对应的层序号 8

Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)_第12张图片

 

4、关键代码

using UnityEngine;

public class Test_LayerAndLayerMask : MonoBehaviour
{

    public GameObject Cube;
    // Start is called before the first frame update
    void Start()
    {
        SetGameObjectLayer(Cube, "TestLayer");
    }

    /// 
    /// 通过层的名称设置层
    /// 
    /// 
    /// 
    private void SetGameObjectLayer(GameObject go, string layerName) {
        int layer = LayerMask.NameToLayer(layerName);

        Debug.Log(GetType()+ "/SetGameObjectLayer()/ layer : "+ layer);

        SetGameObjectLayer(go, layer);
    }

    /// 
    /// 通过层的序号设置层
    /// 
    /// 
    /// 
    private void SetGameObjectLayer(GameObject go, int layer) {
        go.layer = layer;
    }
}

 

四、LayerMask 的介绍和使用

LayerMask 的介绍

LayerMask 实际上是一个位码操作,在Unity3D中一共有32个Layer层,并且不可增加。

 

位运算符

按位运算符:~、|、&、^。位运算符主要用来对二进制位进行操作。

逻辑运算符:&&、||、!。逻辑运算符把语句连接成更复杂的复杂语句。

按位运算符:左移运算符<<,左移表示乘以2,左移多少位表示乘以2的几次幂。

例如:var temp = 14 << 2; 表示十进制数14转化为二进制后向左移动2位。

temp最后计算的值为 14乘以2的平方,temp = 56;

同理,右移运算符>>,移动多少位表示除以2的几次幂。

 

Unity 中的使用:

LayerMask mask = 1 << 3;表示开启Layer3。

LayerMask mask = 0 << 8;表示关闭Layer8。

LayerMask mask = 1<<1|1<<9;表示开启Layer1和Layer9。

LayerMask mask = 0<<4|0<<5;表示关闭Layer4和Layer5。

LayerMask mask = ~(1 << 0) 打开所有的层。

LayerMask mask = ~(1 << 9) 打开除了第9之外的层。

 

上面可以等价为:

LayerMask mask = ~(1<<2|1<<8);表示关闭Layer2和Layer8。

LayerMask mask = 1<<3|0<<5;表示开启Layer3并且同时关闭Layer5。

 

也可以使用层的名称设置,例如:

LayerMask mask  = 1 << LayerMask.NameToLayer(“TestLayer”);  表示开启层名“TestLayer” 的层 。

LayerMask mask  = 0 << LayerMask.NameToLayer(“TestLayer”);  表示关闭层名“TestLayer” 的层 。

 

LayerMask 的使用(Main Camera CullingMask)

1、开始 Main Camera 的 CullingMask 为 Everything

Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)_第13张图片

 

2、编写脚本,设置 Cube 的 Layer 和 Main Camera 的 CullingMask 为 “TestLayer”

Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)_第14张图片

 

3、运行场景,场景中的 Sphere 就不会显示了

运行前:

Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)_第15张图片

运行后:

Unity 基础 之 Layer(层layer) 、LayerMask (遮罩层) 的 总结 和 使用(CullingMask、Ray 射线的使用等)_第16张图片

 

4、关键代码

using UnityEngine;

public class Test_LayerAndLayerMask : MonoBehaviour
{

    public GameObject Cube;
 
    // Start is called before the first frame update
    void Start()
    {
        SetGameObjectLayer(Cube, "TestLayer");

        SetCameraCullingMask("TestLayer");
    }

    /// 
    /// 通过层的名称设置层
    /// 
    /// 
    /// 
    private void SetGameObjectLayer(GameObject go, string layerName) {
        int layer = LayerMask.NameToLayer(layerName);

        Debug.Log(GetType()+ "/SetGameObjectLayer()/ layer : "+ layer);

        SetGameObjectLayer(go, layer);
    }

    /// 
    /// 通过层的序号设置层
    /// 
    /// 
    /// 
    private void SetGameObjectLayer(GameObject go, int layer) {
        go.layer = layer;
    }


    /// 
    /// 通过层的名称设置 Camera CullingMask
    /// 
    /// 
    private void SetCameraCullingMask(string layerName) {
        int layer = LayerMask.NameToLayer(layerName);
        SetCameraCullingMask(layer);
    }

    /// 
    /// 通过层的序号设置 Camera CullingMask
    /// 
    /// 
    private void SetCameraCullingMask(int layer)
    {
        Camera.main.cullingMask = 1 << layer;
    }
}

 

LayerMask 的使用(Physics.Raycast)

 //   layerMask:
 //     A that is used to selectively ignore Colliders when casting a ray.

public static bool Raycast(Vector3 origin, Vector3 direction,  float maxDistance, int layerMask,  QueryTriggerInteraction queryTriggerInteraction);

RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, 1000, 1<

 

附录:

1、批量获取GameObject 及底下子节点的Layer层

private void SetLayerToTheTransAndChildren(Transform theTrans, string layerName) {
        try{
            int[] layers = new int[theTrans.GetComponentsInChildren()];
            foreach (Transform tran in theTrans.GetComponentsInChildren())
            {//遍历当前物体及其所有子物体
                tran.gameObject.layer = LayerMask.NameToLayer(layerName);//更改物体的Layer层 NoWrieframeEffect
            }
        }
        catch (Exception e)
        {
              Debug.Log(e);
        }
}
 


private int[] GetGoLayers(GameObject go)
 {
      try
      {
          var childTransform= go.GetComponentsInChildren();
          int[] layers = new int[childTransform.Length];
          for (int i = 0; i < childTransform.Length; i++)
          {
              layers[i] = childTransform[i].gameObject.layer;
          }
          return layers;
      }
      catch (Exception e)
      {
              Debug.Log(e);
      }
  }

 

2、批量设置GameObject 及子节点同一个Layer层

private void SetLayerToTheTransAndChildren(Transform theTrans, string layerName) {
        foreach (Transform tran in theTrans.GetComponentsInChildren())
        {//遍历当前物体及其所有子物体
            tran.gameObject.layer = LayerMask.NameToLayer(layerName);//更改物体的Layer层 NoWrieframeEffect
        }
    }



private void SetGoLayers(GameObject go, int layer)
  {
       try
       {
           var childrenTrans = go.GetComponentsInChildren();
           for (int i = 0; i < childrenTrans.Length; i++)
           {
               childrenTrans[i].gameObject.layer = layer;
           }
       }
       catch (Exception e)
       {
           Debug.LogError(e.ToString());
       }
   }

 

你可能感兴趣的:(基础,Unity,Unity,Layer,LayerMask,层)