在Unity3D中一共有32个Layer层,并且不可增加。Unity使用了一个int32类型来表示Layer层,其本质在于用一个32位来表示32层,unity存储层的方式是将该位置为1其余位置为0来表示,比如声明了一个Ground的层其层编号为9,那么在unity的存储方式为000000000000000000000001000000000(二进制),将第九位置为1其余的置为0来表示该层,将这串二进制转换为Int32类型为512
下面在来叙述一下LayerMask里面的三个函数
LayerMask.NameToLayer(string)
LayerMask.LayerToName(int)
LayerMask.GetMask(string)
LayerMask.NameToLayer(string)表示的是根据层名称返回在LaskMask里面的层索引,比如说上面我声明的Ground的层,那就应该返回9(切记不是512)
同理LayerMask.LayToName(int)则是根据层索引,返回层名称,比如说我写入9,那么返回的应该是Ground
LayerMask.GetMask(string) 表示的是根据层名称返回其存储值,比如说我输入Ground他返回的应该是512
了解这一点之后我们再来讲讲射线检测
Physics.Raycast(ray, out raycastHit,1 << LayerMask.NameToLayer("Ground"))
这是我们在网上经常能看到的射线检测代码
很多人都不理解为什么LayerMask.NameToLayer("Ground")前面要加一个位运算符<<
我之前在没有查询API是的写法是这样的:
Physics.Raycast(ray, out raycastHit, LayerMask.NameToLayer("Ground"))
但是怎么检测都不成功,后来我经过测试发现Physics.Raycast里面所需要传递的int值应该是LayerMask的存储值,比如说如果检测Ground那应该传递512进去,而不是传递层索引9(这一点坑了我很久)
所以说再返回看这个检测方法1 << LayerMask.NameToLayer("Ground"),将1左移9位,得到的刚好就是512。
了解上面这一点后我们这个函数的位置就可以进行更换了比如说
Physics.Raycast(ray, out raycastHit, LayerMask.GetMask(“Ground”));
因为GetMask返回的就是其层的存储值512,也就不需要过多的操作。