转自:https://www.cnblogs.com/mimime/p/6145744.html
Unity是用 int32来表示32个Layer层,int32用二进制来表示一共有32位。
0000 0000 0000 0000 0000 0000 0000 0000
31 0
看几个例子
开启layer 2
LayerMask mask = 1<<2;
其中 <<左边的 1表示有[开启],0表示没有该layer[忽略] 。右边的2表示左移2位即是 layer2层的位置。
开启layer 0和layer 2
LayerMask mask = 1 << 0 | 1 << 2;
开启Layer0 并关闭 Layer2
LayerMask mask = 1 << 0 | 0 << 2
开启Layer Default
LaserMask mask=1 << LayserMask.NameToLayer(“Default”);
脚本例子
下面是一个脚本例子,把它绑定在Camera上
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(Camera))]
public class LayerMaskTest : MonoBehaviour { //打开Npc层,变1 或 运算符 private void Show() { //camera.cullingMask |= 1 << LayerMask.NameToLayer("Npc"); camera.cullingMask = (int) 1<<LayerMask.NameToLayer("Npc");//写法二 } // 关闭Npc层,变0 按位与 & 按位取反 ~ private void Hide() { camera.cullingMask &= ~(1 << LayerMask.NameToLayer("Npc")); } // 开关Npc层,按位异或 ^ private void Toggle() { camera.cullingMask ^= 1 << LayerMask.NameToLayer("Npc"); } void OnGUI() { if (GUILayout.Button("Show")) Show(); if (GUILayout.Button("Hide")) Hide(); if (GUILayout.Button("Toggle")) Toggle(); } }
实际应用
Unity的碰撞检测
static bool Raycast(Vector3 origin, Vector3 direction, float distance = Mathf.Infinity, int layerMask = DefaultRaycastLayers);
物理碰撞互斥
我们项目中自己写的物理碰撞互斥
//开启Npc层的碰撞 LayerMask mask = 1 << (int)GameLayerDef.Npc; float bounds = 2; RaycastHit2D raycastHit = Physics2D.CircleCast(transform.position, bounds, Vector2.right, Mathf.Infinity, mask.value); //-GoOn-//Unity中是用int32来表示32个Layer层。int32表示二进制一共有32位(0—31)。 在Unity中可编辑的Layer如下图所示:
在Unity中每个GameObject都有Layer属性,默认的Layer都是Default。在Unity中可编辑的Layer共有24个(8—31层),官方已使用的是0—7层,默认不可编辑!
LayerMask实际上是一个位码操作,在Unity3D中一共有32个Layer层,并且不可增加。
位运算符
按位运算符:
~、|、&、^
。位运算符主要用来对二进制位进行操作。逻辑运算符:
&&、||、!。
逻辑运算符把语句连接成更复杂的复杂语句。按位运算符:左移运算符
<<
,左移表示乘以2,左移多少位表示乘以2的几次幂。举个栗子:
var temp = 14 << 2;
表示十进制数14转化为二进制后向左移动2位。temp最后计算的值为 14乘以2的平方,temp = 56;
同理,右移运算符
>>
,移动多少位表示除以2的几次幂。具体可以转到博客:按位运算符.
上面是个基础知识的补充。
在Unity中是用LayerMask
Layers
官方给出的描述是: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使用。
在代码中使用时如何开启某个Layers?
LayerMask mask = 1 << 你需要开启的Layers层。
LayerMask mask = 0 << 你需要关闭的Layers层。
举几个个栗子:
LayerMask mask = 1 << 2; 表示开启Layer2。
LayerMask mask = 0 << 5;表示关闭Layer5。
LayerMask mask = 1<<2|1<<8;表示开启Layer2和Layer8。
LayerMask mask = 0<<3|0<<7;表示关闭Layer3和Layer7。
上面也可以写成:
LayerMask mask = ~(1<<3|1<<7);表示关闭Layer3和Layer7。
LayerMask mask = 1<<2|0<<4;表示开启Layer2并且同时关闭Layer4.
代码:
using UnityEngine; using System.Collections; public class example : MonoBehaviour { LayerMask mask = ~(1<<3|1<<7); void Update() { if (Physics.Raycast(transform.position, transform.forward, 100, mask.value)) Debug.Log("Hit something"); } }