如何在检查碰撞的同时将 RigidBody2D 移动到某个位置
How to move a RigidBody2D to a position while still checking for collision
我目前正在 Unity 中创建一个游戏,您可以在其中使用 OnMouseDrag()
、CircleCollider2D
和 RigidBody2D
移动一个球。这就是我设置球位置的方式:
private void OnMouseDrag()
{
Vector2 mouseInWorld = Camera.main.ScreenToWorldPoint(Input.mousePosition);
playerRb.position = new Vector3(mouseInWorld.x, mouseInWorld.y, 0);
}
我仍然希望在鼠标四处移动时球在碰撞时滑动。有办法吗?
我试过 RigidBody2D.MovePosition()
,但球从一个点跳到另一个点,Raycast
s 但也无法正常工作。
编辑:
这就是我现在得到的:
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);
}
但请注意,如果小球无法一直移动到鼠标,则可能会导致拖动结束。所以,相应地计划。
我目前正在 Unity 中创建一个游戏,您可以在其中使用 OnMouseDrag()
、CircleCollider2D
和 RigidBody2D
移动一个球。这就是我设置球位置的方式:
private void OnMouseDrag()
{
Vector2 mouseInWorld = Camera.main.ScreenToWorldPoint(Input.mousePosition);
playerRb.position = new Vector3(mouseInWorld.x, mouseInWorld.y, 0);
}
我仍然希望在鼠标四处移动时球在碰撞时滑动。有办法吗?
我试过 RigidBody2D.MovePosition()
,但球从一个点跳到另一个点,Raycast
s 但也无法正常工作。
编辑: 这就是我现在得到的:
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);
}
但请注意,如果小球无法一直移动到鼠标,则可能会导致拖动结束。所以,相应地计划。