如何在检查碰撞的同时将 RigidBody2D 移动到某个位置

How to move a RigidBody2D to a position while still checking for collision

我目前正在 Unity 中创建一个游戏,您可以在其中使用 OnMouseDrag()CircleCollider2DRigidBody2D 移动一个球。这就是我设置球位置的方式:

 private void OnMouseDrag()
 {
     Vector2 mouseInWorld = Camera.main.ScreenToWorldPoint(Input.mousePosition);
     playerRb.position = new Vector3(mouseInWorld.x, mouseInWorld.y, 0);
 }

我仍然希望在鼠标四处移动时球在碰撞时滑动。有办法吗?

我试过 RigidBody2D.MovePosition(),但球从一个点跳到另一个点,Raycasts 但也无法正常工作。

编辑: 这就是我现在得到的:

playerRb.velocity = new Vector3(mouseInWorld.x - playerRb.position.x, mouseInWorld.y - playerRb.position.y, 0);

现在的问题是,球滞后于 mousePosition。

当您使用 RigidBody.MovePosition 时,您不会调用物理引擎,因此它会忽略碰撞。如果您希望发生碰撞,您需要使用 RigidBody.Velocity。

进行此更改需要您对代码进行一些更改,因为您提供给 RigidBody.Velocity 的是速度而不是位置,因此您需要计算 x,y 中所需的速度(和 z,如果你在 3d 中)到达目的地。

我邀请您阅读有关速度的 Unity 页面以获取更多信息 https://docs.unity3d.com/ScriptReference/Rigidbody-velocity.html

注意:这将使 player/ball 坚持碰撞。

修改速度可能会导致球在与墙壁碰撞时意外反弹。我会为此使用 CircleCast,检查它是否命中任何东西,然后相应地使用 MovePosition

float cursorDepth;
Rigidbody2D playerRb;
CircleCollider cc;

void Awake()
{
   playerRb = GetComponent<Rigidbody2D>();
   cc = GetComponent<CircleCollider>();
}

private void OnMouseDrag()
{
    Vector2 mouseInWorld = Camera.main.ScreenToWorldPoint(Input.mousePosition);

    Vector2 posToMouse = mouseInWorld - playerRb.position;

    RaycastHit2D hit = Physics2D.CircleCast(playerRb.position, 
            cc.radius * transform.lossyScale.x, posToMouse, posToMouse.magnitude); 

    if (hit.collider != null)
    {
        mouseInWorld = hit.centroid;
    }

    playerRb.MovePosition(mouseInWorld);
}

但请注意,如果小球无法一直移动到鼠标,则可能会导致拖动结束。所以,相应地计划。