Unity Physics2D.Raycast击中了自己

我正在尝试使用Physics2D.Raycast来检查玩家是否在地面上(我知道还有其他方法来检查玩家是否在地面但我认为光线投射是最可靠的)。 问题是在我的场景中它将玩家本身作为命中返回,我真的不明白为什么以及我该怎么做。 我的代码(在PlayerController )如下:

  public bool IsGrounded () { Bounds bounds = this.playerCollider.bounds; Vector3 rayOrigin = bounds.center; rayOrigin.y -= bounds.extents.y; RaycastHit2D hit = Physics2D.Raycast (rayOrigin, Vector2.down, 0.1f); if (hit.collider != null) { Debug.Log ("Collider is: " + hit.collider.name); } return hit.collider != null; } 

我可以使用以下方法调试铸造射线:

 Debug.DrawLine (rayOrigin, new Vector3 (rayOrigin.x, rayOrigin.y - 0.1f, rayOrigin.z), Color.magenta); 

…并按预期进行转换,而Debug.Log始终报告“播放器”本身,我不知道它是如何可能的。 那有什么不对?

PS。 我正在使用Unity 5.3

问题出现是因为您的播放器在光线投射开始时重叠。 有几种方法可以解决这个问题:

1.Disable Queries在碰撞器中开始

转到编辑 – > 项目设置 – > 物理2D,然后确保未选中查询在碰撞器中启动 。 更改后,您的代码运行正常。 这是一个截图:

在此处输入图像描述

2.另一个解决方案是使用layers.Raycasting但忽略Player层。在你这样做之前,确保创建一个名为Ground的图层并将你的地面GameObject放到Ground图层然后创建另一个名为Player的图层并将你的玩家放入Player层。 我们现在可以使用bitwise符从光线投射中排除 Player层。

在此处输入图像描述

现在,我们假设Player层数为9 。 下面的代码应该可以解决您的问题。

 public int playerLayer = 9; int layerMask = ~(1 << playerLayer); //Exclude layer 9 RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.down, 0.1f, layerMask); 

就是这样 。 这两个都能够解决你的问题。

对于其他人阅读,下面是其他方法,可以轻松检测Player何时触摸地板而不使用Physics2D.Raycast或完成上述所有操作。

只需连接到Player

 public class Player : MonoBehaviour { public LayerMask groundLayer; Collider2D playerCollider; bool grounded; void Start() { playerCollider = gameObject.GetComponent(); } public bool IsGrounded() { grounded = Physics2D.OverlapCircle(playerCollider.transform.position, 1, groundLayer); return grounded; } } 

或者您可以使用IsTouchingLayers

 public bool IsGrounded() { grounded = grounded = playerCollider.IsTouchingLayers(groundLayer.value); return grounded; } 

Vector2.down向量不会始终显示对象空间的向下向量。 您可以使用-transform.up

此外,如果可以接受,您可以添加一些填充到光线的起点,如rayOrigin.y += 0.0001f;