unity Physics2D.Raycast 打自己
Unity Physics2D.Raycast hits itself
我正在尝试使用 Physics2D.Raycast
来检查玩家是否在地面上(我知道还有其他方法可以检查玩家是否在地面上,但我认为光线投射最靠谱)。
问题是在我的场景中 returns 玩家本身被击中了,我真的不明白为什么以及我应该做什么。
我的代码(在 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
总是报告 "Player" 本身,我不知道这怎么可能。那怎么了?
ps。我正在使用 Unity 5.3
Vector2.down 向量并不总是呈现对象 space 的下向量。您可以使用 -transform.up
。
此外,如果可以接受,您可以在光线的起点添加一些填充,例如 rayOrigin.y += 0.0001f;
。
出现此问题是因为您的播放器在光线投射开始时重叠。有几种方法可以解决此问题:
1.禁用查询在碰撞器中启动.
转到编辑->项目设置->Physics 2D 然后确保Queries Start In Colliders 未选中。您的代码 运行 更改后没问题。这是屏幕截图:
2。另一个解决方案是使用 layers.Raycasting 但忽略 Player
layer.Before 你这样做,确保创建一个图层调用 Ground
并将你的地面游戏对象放入 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);
就是这样。这两个都能解决你的问题。
对于阅读的其他人,下面是无需使用 Physics2D.Raycast
或执行上述所有操作即可轻松检测 Player
何时接触地板的其他方法。
只需附加到 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;
}
我正在尝试使用 Physics2D.Raycast
来检查玩家是否在地面上(我知道还有其他方法可以检查玩家是否在地面上,但我认为光线投射最靠谱)。
问题是在我的场景中 returns 玩家本身被击中了,我真的不明白为什么以及我应该做什么。
我的代码(在 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
总是报告 "Player" 本身,我不知道这怎么可能。那怎么了?
ps。我正在使用 Unity 5.3
Vector2.down 向量并不总是呈现对象 space 的下向量。您可以使用 -transform.up
。
此外,如果可以接受,您可以在光线的起点添加一些填充,例如 rayOrigin.y += 0.0001f;
。
出现此问题是因为您的播放器在光线投射开始时重叠。有几种方法可以解决此问题:
1.禁用查询在碰撞器中启动.
转到编辑->项目设置->Physics 2D 然后确保Queries Start In Colliders 未选中。您的代码 运行 更改后没问题。这是屏幕截图:
2。另一个解决方案是使用 layers.Raycasting 但忽略 Player
layer.Before 你这样做,确保创建一个图层调用 Ground
并将你的地面游戏对象放入 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);
就是这样。这两个都能解决你的问题。
对于阅读的其他人,下面是无需使用 Physics2D.Raycast
或执行上述所有操作即可轻松检测 Player
何时接触地板的其他方法。
只需附加到 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;
}