官方文檔對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); 可以在層名和層序號之間互相轉換,都是靜態方法直接用類名調用。
例子下載: CalcLayer_D.unitypackage (5 K) 下載次數:17
當cullingMask為Nothing時,值是0。 當cullingMask設置為everything時,值是-1。這時如果有層要關閉,就減去這個層的值。 比如第8層的值是 256。那關閉第8層后的值是 -257[-1-(1<<9)] 因為設置everything時的數值比較特別,和算法沒關系。所以代碼我就不做修改了。如果要使用負數可以自己轉換一下。
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]); } } }