总起:Camera.culling Mask,摄像头的剔除掩码,即有选择性的踢掉对应摄像机能渲染的部分场景。操作上,主要通过勾选不同的层,来选择渲染
culling Mask本质为一个Int类型的值,32位,每一位代表一层,比如开启第一层,cullingMask = 1<<2。1<<index,1的二进制是00000000 00000001,1<<index就是左移index位,如1<<2,就是00000000 00000100。当相机什么都不渲染,即cullingMask为Nothing时,cullingMask等于0,即32个0,当相机渲染everything时,cullingMask为-1,即32个1(补码)
在某些情况下,我们需要动态的变化Camera的culling Mask:
camera.cullingMask = ~(1 << x); // 渲染除x层的所有层
camera.cullingMask &= ~(1 << x); // 关闭x层
camera.cullingMask |= (1 << x); // 打开x层
camera.cullingMask = 1 << x + 1 << y + 1 << z; // 摄像机只显示第x层,y层,z层.
通过位移运算符,可以添加选中层。 假设要摄像机只显示第10层,11层,12层。写成:
camera.cullingMask = 1<<10 + 1<<11 + 1<<12;
不用位的与或操作,可以如下操作达到同样效果。如果有层要关闭,就减去这个层的值。 比如第8层的值是 256。那关闭第8层后的值是 -257[-1-(1<<9)]
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]);
}
}
}