Camera的LayerMask

来源:互联网 发布:淘宝客服催单算提成吗 编辑:程序博客网 时间:2024/06/06 20:15
在操作 LayerMask 时常令一些初学者摸不着头脑下面简单说一下层的开关方法:

1.首先引入'|'、'&'、'~'的概念
与(交集):10000001 & 10000100 == 10000000
或(并集):10000001 | 10000100 == 10000101
非(反转):10000001 == ~01111110

2.int myLayerMask = 1 << curLayer;
等式右侧 curLayer 代表Inspector/Layer中的某一层
等号左侧是通过一个数来保存多个层的信息
他是怎么做到的呢?
其实是用 myLayerMask = 00000000 方式来保存的
即 myLayerMask = 1 << 3 ---> myLayerMask == 00001000
这时层级中的第3层被开启,其余层处于关闭状态
另外,需注意的是,层的序号是从0开始计算的
因此,上面的操作相当于使用二进制方法进行一对多表现方式的转化过程

3.实例讲解
有了上面铺垫,我们就可以轻松的对多个Layer进行开关了
1)开启1、2层
camera.cullingMask = (1 << 1) | (1 << 2);
2)开启除2层外的所有层
camera.cullingMask = ~(1 << 2);
3)开启除1、2、4层外的所有层
camera.cullingMask = ~((1 << 1) | (1 << 2) | (1 << 4));

官方文档对CullingMask的注释只是说了通过位移运算符,可以添加选中层。 假设要摄像机只显示第10层,11层,12层。写成:

camera.cullingMask = 1<<10 + 1<<11 + 1<<12;

但是为什么要这样觉得很奇怪。于是研究了一下。
通过print发现,随便一个层,它前面所有层的和,不会大于它自身的值。 这样的话,可以只用一个int变量保存多个类似布尔型的数据,节省内存。
然后我写了一个读取CullingMask值的函数。智商拙技。如果用二进制去做更快 传入值是CullingMask的值,输出的int数组是同时选中了哪几个层。
[2012/12/10补充]      最近又发现2个LayerMask的”隐藏方法“,帮助文档里应该没有: public static extern string LayerToName (int layer); public static extern int NameToLayer (string layerName); 可以在层名和层序号之间互相转换,都是静态方法直接用类名调用。

public int[] calcMask(int val){  int[] result = null;    int flag1 = 0;  int flag2 = 0;  List<int> tmpLayers = new List<int>();  List<int> resultLayers = new List<int>();    for(int i=1; i<=val; i*=2)  {   tmpLayers.Add(i);  }//把val和首个层之间的层添加入数组.数组元素从小到大顺序  tmpLayers.Add(tmpLayers[tmpLayers.Count-1]*2);    //使用递归计算选中的层  recursiveCalcMask(val, tmpLayers, ref resultLayers);    for(int i=0; i< resultLayers.Count; i++)  {   resultLayers[i] = (int)Mathf.Log(resultLayers[i], 2);   //用Mathf.Log以2为底数。去求图层编号。  }    result = new int[resultLayers.Count];  resultLayers.CopyTo(result);    return result;}public void recursiveCalcMask(int val, List<int> arr, ref List<int> outArr){  for(int i= 0; i<arr.Count; i++)  {   if(arr[i] == val)   {    outArr.Add(val);    break;   }   else if(arr[i] < val && arr[i+1] > val)   {    recursiveCalcMask(val - arr[i], arr, ref outArr);    outArr.Add(arr[i]);   }  }}


参考:
http://blog.sina.com.cn/s/blog_4b0296020101fvsx.html
http://www.cnblogs.com/88999660/archive/2013/03/14/2959439.html

!!!!!!!!!!!!!!!!!!!!!!!!

当然最好借用

LayerMask

比如 屏蔽多个Layer:
                string[] layers = {"Water", "UI"};\this.GetComponent<Camera>().cullingMask = LayerMask.GetMask(layers);
0 0