Unity的Physics.Raycast()方法,为什么指定层遮罩后还会 ...
错误代码public class ChoiceWeapon : MonoBehaviour
{
Ray ray;
private void Update()
{
//从摄像机到鼠标指向位置发射射线
Vector2 mousePos = Input.mousePosition;
ray = Camera.main.ScreenPointToRay(mousePos);
TestRay();
}
private void TestRay()
{
RaycastHit hitInfo;
//下面的if,判断射线是否检测碰撞到Enemy层;
if(Physics.Raycast(ray, out hitInfo, LayerMask.GetMask("Enemy")))
{
Debug.Log(hitInfo.transform.name);
}
}
}
上述代码,妄想通过射线,检测是否碰撞Enemy层的物体,然而在实际运行过程中,会发现射线碰撞所有物体的时候,都会执行if内的代码,即使不是Enemy层,也会被检测到。
不使用GetMask()方法,用左移运算符也是如此;
if(Physics.Raycast(ray, out hitInfo,1<<2))
且当第三个参数值较小的时候,无法检测到任何层的物体。
原因
通过检查Raycast()方法的重载可以发现,并没有bool Physics.Raycast(Ray ray,out RaycastHit hitInfo, int layerMask)的重载。
只有以下两种重载形式:
当我们使用Physics.Raycast(ray,out hitInfo, LayerMask.GetMask(&#34;Enemy&#34;))时,其实加载的是上面的那个重载,只有三个参数的重载。
而LayerMask.GetMask(&#34;Enemy&#34;))被当做了maxDistance,这里有些人可能会疑惑,简单解释一下,层是用int的不同位来表示的。
如上图,Default就是1,TransparentFX就是1<<1,IgnoreRaycast就是1<<2,依此类推,Enemy就是1<<6。
LayerMask.GetMask(&#34;Enemy&#34;)等价于1<<6;
所以此时第三个参数是int类型,并没有报错。我们使用的层遮罩,就被当成了一个射线的最远距离,这也是为什么,当层遮罩的值很小时,无法检测到任何物体,因为指定的射线最远距离太短了,碰不到任何物体。
解决方案
而我们想要使用层遮罩的话,就要使用下面这个重载。
同时指定最远距离和层遮罩。
改动后的if代码:
if(Physics.Raycast(ray, out hitInfo, Mathf.Infinity, LayerMask.GetMask(&#34;Enemy&#34;)))
{
//......
}
Mathf.Infinity是正无穷大。
改完后,就可以正常的检测碰撞Enemy层物体了。
页:
[1]