我正在尝试使用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
答案 0 :(得分:4)
问题出现是因为您的播放器在光线投射开始时重叠。解决这个问题的方法很简单:
1 。禁用查询在碰撞器中开始。
转到修改 - > 项目设置 - > 物理2D ,然后确保查询在碰撞器中开始未选中。更改后,您的代码运行正常。这是一个截图:
2 。另一个解决方案是使用layers.Raycasting但忽略Player
图层。在执行此操作之前,请务必创建一个名为Ground
的图层并将其放入将GameObject接地到Ground
图层然后创建另一个名为Player的图层,并将您的玩家放入Player
图层。我们现在可以使用bitwise
运算符从光线投射中排除 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<Collider2D>();
}
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;
}
答案 1 :(得分:-1)
Vector2.down向量不会始终显示对象空间的向下向量。您可以使用-transform.up
。
此外,如果可以接受,您可以在光线的起始点添加一些填充,例如rayOrigin.y += 0.0001f;
。