简体   繁体   中英

Unity - best way to drag a RigidBody2D Gameobject by mouse/touch

I am creating a 2D game in Unity and wanted to see if anyone has any suggestion on how I can improve the script below which I am using to drag a paddle in a breakout/arkanoid style game. I know there are more complex ways to drag objects but this works ok for me but the only issue I encounter is that when I test my game on a mobile device the dragging is not 100% sharp and when I stop dragging the paddle seems to lag ever so slightly. I don't have any issues with my mobile device as I have played other breakout games I downloaded from the Play store and the dragging is very crisp.

The script below is attached to the paddle.

Vector3 dist;
float posX;
float posY;

void OnMouseDown(){
    dist = Camera.main.WorldToScreenPoint(transform.position);
    posX = Input.mousePosition.x - dist.x;
    posY = Input.mousePosition.y - dist.y;

}

void OnMouseDrag(){
    Vector3 curPos = new Vector3(Input.mousePosition.x - posX, Input.mousePosition.y - posY, dist.z);  

    Vector3 worldPos = Camera.main.ScreenToWorldPoint(curPos);

    transform.position = worldPos;
}

I would advise doing your translation of the x and y-axis values using the mouse's position as it's being dragged via the subtracted difference between what the mouse's position value was as it's first pressed down.

A summary of that would be:

  1. Store a 2D vector as a private field, called previousPos (so mousedown and mousemove can both access it) and set it's value to the result of the mouse's current position.
  2. In the mouse drag function, get the mouse position again and assign the value to a 2D vector called currentPos and subtract that from the previousPos, which gives you the x and y-axis values to set the paddle's transform position to.
  3. Then update the previousPos at the end of the drag function, and assign the value of currentPos to it so that next time around it gives the new change and not the aggregated change.

*You probably want to have a boolean that you set to true when mouse is down and at the end of the drag set it to false. Use that bool in the drag as a check to see if you need to set the paddle position in the first place (only set paddle position if the boolean is true) -- Not sure if unity does this for you by only firing mouse dragged when the mouse is down or not.

An example in code:

private Vector2 _previousPos;
private bool _isMouseDown;

void OnMouseDown(){
    _isMouseDown = true; //because we're in the on mouse down function
    _previousPos = Input.mousePosition; //get the current mouse position
}

void OnMouseDrag(){
    if(!_isMouseDown)
        return;

    Vector2 currentPos = Input.mousePosition; //get updated mouse pos 
    Vector2 paddlePos = currentPos - previousPos; //the delta change

    transform.position = paddlePos; //new paddle position

    _isMouseDown = false; //drag is complete, mouse btn is no longer down
    _previousPos = currentPos; //reset previous pos for next mouse move
}

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