简体   繁体   中英

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

I am currently creating a game in Unity, in which you move a ball around using OnMouseDrag() , a CircleCollider2D and a RigidBody2D . This is how I set the position of the ball:

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

I still want the ball to slide on collision while the mouse moves around. Is there a way to do this?

I have tried RigidBody2D.MovePosition() , but the ball jumped around from one point to another, and Raycast s but couldn't get that to work either.

EDIT: This is what I've got now:

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

Now the problem is, that the ball lags behind the mousePosition.

When you use RigidBody.MovePosition, you don't call the physics engine and so it ignores collisions. If you want collisions to happen you need to use RigidBody.Velocity instead.

Doing this change will require you to make some change to your code though because what you give to RigidBody.Velocity is a velocity and not a position so you will need to calculate the velocity required in x,y (and z if you are in 3d) to reach your destination.

I invite you to read the Unity page about velocity for more info https://docs.unity3d.com/ScriptReference/Rigidbody-velocity.html

Note: This will make the player/ball stick to collisions.

Modifying the velocity could cause the ball to bounce around unexpectedly when the ball collides with the wall. I would use a CircleCast for this, check if it hit anything, then use MovePosition accordingly:

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);
}

But notice that if the ball can't move all the way to the mouse, it might cause the drag to end. So, plan accordingly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM