- Home /
Rotate 2d object on mouse drag relative to its position
Hi. I need help figuring out how to rotate a object on mouse drag but to make it so that the object starts rotating from its original position but not from the mouse click position. My scene uses an orthographic camera that is set to z:-10 and Iv'e pretty much got the general rotation part figured out and working.
Here's the code I'm using:
using UnityEngine;
using System.Collections;
public class TestScript : MonoBehaviour {
Camera myCam;
private Vector3 mousePos;
private Vector3 mousePosOnMouseDown;
private Vector3 clickOffset;
// Use this for initialization
void Start () {
myCam=Camera.main;
}
void Update () {
mousePos = myCam.ScreenToWorldPoint(Input.mousePosition);
//This fires only on the frame the button is clicked
if(Input.GetMouseButtonDown(0))
{
mousePosOnMouseDown = new Vector3(mousePos.x,mousePos.y,transform.position.z);
clickOffset = transform.position-mousePosOnMouseDown;
}
//This fires while the button is pressed down
if(Input.GetMouseButton(0))
{
Vector3 norm = mousePos-transform.position;
float angle = Mathf.Atan2(norm.x, norm.y) * Mathf.Rad2Deg;
transform.eulerAngles = new Vector3(angle,90,90);
}
}
}
And here's a short clip of it working :[https://docs.google.com/file/d/0B0ozmyp9_wwiQm4zd0xFR2xjVVU/edit?usp=sharing][1] [1]: https://docs.google.com/file/d/0B0ozmyp9_wwiQm4zd0xFR2xjVVU/edit?usp=sharing
If you look at the video you can see the object snapping to the point where I clicked. And right now it should, because I'm not actually doing anything to prevent that in my code. What I would like to achieve is: when I click on the mouse button the object keeps it's rotation but when I start dragging the mouse, then the object starts rotating relative to the direction and amount i have dragged.
It should be quite simple, at least that's what I thought 3 days ago, and before running out of different ideas how to even search for a solution.
So if anybody has an idea how to make this happen, then please let me know
Answer by robertbu · Sep 28, 2013 at 03:56 PM
You have a couple of things going on here that need to be addressed. First, them mouse position is in screen coordinates...that is pixels measured from the lower left corner. Your game object lives in world space. Your code is mixing the two without conversion. Second issue: Atan2 takes y,x, not x,y as parameters. As for fixing your problem, one way is to record the angle when the mouse goes down, then you add that angle as the mouse is moved.
Line 31 confuses me about how you have your scene organized. The following rewrite of your code assumes the camera is facing positive 'Z' (as it would in a new scene).
using UnityEngine;
using System.Collections;
public class TestScript : MonoBehaviour {
private Camera myCam;
private Vector3 screenPos;
private float angleOffset;
void Start () {
myCam=Camera.main;
}
void Update () {
//This fires only on the frame the button is clicked
if(Input.GetMouseButtonDown(0)) {
screenPos = myCam.WorldToScreenPoint (transform.position);
Vector3 v3 = Input.mousePosition - screenPos;
angleOffset = (Mathf.Atan2(transform.right.y, transform.right.x) - Mathf.Atan2(v3.y, v3.x)) * Mathf.Rad2Deg;
}
//This fires while the button is pressed down
if(Input.GetMouseButton(0)) {
Vector3 v3 = Input.mousePosition - screenPos;
float angle = Mathf.Atan2(v3.y, v3.x) * Mathf.Rad2Deg;
transform.eulerAngles = new Vector3(0,0,angle+angleOffset);
}
}
}
Hi. Thank you very much for the answer. I'll explain my scene a little bit. $$anonymous$$y camera is positioned at x:0;y:0;z:-10; rotation is 0; The magenta gameobject is a simple plane that was created via custom plane script. When I add the plane to the scene then I have to set it's x rotation to 270 if I'm going to add any textures to that. There's probably a better way to do this. Now about the script. I replaced my custom plane with a regular unity cube , but there's still some snapping / jumping occurring. $$anonymous$$ade another demo video
I also tried making a completely new project and testing the script on there but that didn't change anything.
You are right. The script had a couple of issues. I've edited the script and fixed the problems. Start a new scene, add the script to a cube, and hit play. To address your plane issue, either use the new Quad game object (GameObject>Create Other>Quad) or use the CreatePlane Wiki editor script and create a vertical plane.
Oh. One more thing. Whats the role of the transform.right when calculating the objects original angle? Just trying to understand how and why it works.
'angleOffset' is the delta between the angle of the mouse relative to the pivot and the angle of the game object. I'm using transform.right to get the angle of the object. I could have just used transform.eulerAngles.z. There are some real gotchas with using eulerAngles, but in this case it would have been fine.