我正在尝试使用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.禁用从碰撞器开始的查询。
转到“编辑”->“项目设置”->“物理2D”,然后确保未选中“从碰撞器开始查询”。更改后,您的代码运行良好。这是屏幕截图:
2,另一种解决方案是使用图层,进行射线广播但忽略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;
}
关于c# - Unity Physics2D.Raycast流行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38191659/