- Home /
Rotation Question
I'm using the following code to rotate an object on the screen with a mouse drag. It's working pretty good, but I would like to be able to limit the rotation by 90 deg in either x axis direction (so that the object cannot be turned upside down). Also, on the same x-axis, I would like the area of the 3D object facing the camera to be the area that rotates upward and downward at any given time. Not sure how to make this work! Here's the current code:
var speed : int;
var friction : float;
var lerpSpeed : float;
private var xDeg : float;
private var yDeg : float;
private var fromRotation : Quaternion;
private var toRotation : Quaternion;
function Update () {
if(Input.GetMouseButton(0)) {
xDeg -= Input.GetAxis("Mouse X") * speed * friction;
yDeg -= Input.GetAxis("Mouse Y") * speed * friction;
fromRotation = transform.rotation;
toRotation = Quaternion.Euler(yDeg,xDeg,0);
transform.rotation = Quaternion.Lerp(fromRotation,toRotation,Time.deltaTime * lerpSpeed);
}
}
Answer by save · Jul 19, 2011 at 10:06 AM
The problem with the script you've posted is that you'll get movement inconsistency at higher speeds, also if you'd like to be able to rotate several objects individually in one scene it won't let you. It's not very clear what you want the outcome to be, therefore I've made two versions of the script:
Parented version
private var smoothSpeed : int = 10; //How fast should the object return to position
private var speed : int = 20; //Sensitivity for mouse movement
private var mouseMovement : Vector2; //Stored mouse axis
private var mouseToRot : Quaternion; //Rotation variable
private var rotClamp : int = 90; //Clamped degrees
private var selected : boolean = false; //Checks for selection
function Start () {
transform.parent = Camera.main.transform;
}
function Update () {
if(Input.GetMouseButton(0) && selected) {
mouseMovement -= Vector2(-Input.GetAxis("Mouse Y")*speed, Input.GetAxis("Mouse X")*speed); //Set mouseMovement to mouse movement on left mousebutton down
} else {
mouseMovement[0] = Mathf.SmoothStep(mouseMovement[0], 0, Time.deltaTime*smoothSpeed); //Return to position
mouseMovement[1] = Mathf.SmoothStep(mouseMovement[1], 0, Time.deltaTime*smoothSpeed); //Return to position
selected = false; //Set selected to false as we no longer push the left mousebutton
}
mouseToRot = Quaternion.Euler(Mathf.Clamp(mouseMovement[0], -rotClamp, rotClamp), Mathf.Clamp(mouseMovement[1], -rotClamp, rotClamp), 0); //Use Mathf.Clamp to clamp degrees
transform.localRotation=mouseToRot; //Apply rotation to Transform
}
function OnMouseDown () {
selected = true; //Selected will go true on left mousebutton down on objects with a collider
}
Copied rotation version
private var smoothSpeed : int = 10; //How fast should the object return to position
private var speed : int = 20; //Sensitivity for mouse movement
private var mouseMovement : Vector2; //Stored mouse axis
private var cameraRotation : Quaternion; //Stored camera rotation
private var mouseToRot : Quaternion; //Rotation variable
private var rotClamp : int = 90; //Clamped degrees
private var selected : boolean = false; //Checks for selection
function Update () {
if(Input.GetMouseButton(0) && selected) {
mouseMovement -= Vector2(-Input.GetAxis("Mouse Y")*speed, Input.GetAxis("Mouse X")*speed); //Set mouseMovement to mouse movement on left mousebutton down
} else {
mouseMovement[0] = Mathf.SmoothStep(mouseMovement[0], 0, Time.deltaTime*smoothSpeed); //Return to position
mouseMovement[1] = Mathf.SmoothStep(mouseMovement[1], 0, Time.deltaTime*smoothSpeed); //Return to position
selected = false; //Set selected to false as we no longer push the left mousebutton
}
cameraRotation = Camera.main.transform.rotation; //Store rotation of Main Camera
mouseToRot = Quaternion.Euler(-cameraRotation.eulerAngles.x+Mathf.Clamp(mouseMovement[0], -rotClamp, rotClamp), -cameraRotation.eulerAngles.y+Mathf.Clamp(mouseMovement[1], -rotClamp, rotClamp), cameraRotation.eulerAngles.z); //Use Mathf.Clamp to clamp degrees
transform.rotation=mouseToRot; //Apply rotation to Transform
}
function OnMouseDown () {
selected = true; //Selected will go true on left mousebutton down on objects with a collider
}
The Parented version will make the object child itself and use the localRotation derived from the camera rotation. The Copied rotation version will store the cameras rotation values and apply to the final rotation of the object.
"I would like the area of the 3D object facing the camera to be the area that rotates upward and downward at any given time."
To add a rotation just create a floating variable that you add to the final eulers of the object:
var extraRotation : float = 45.0;
mouseToRot = Quaternion.Euler(-cameraRotation.eulerAngles.x+extraRotation+Mathf.Clamp(mouseMovement[0], -rotClamp, rotClamp), -cameraRotation.eulerAngles.y+Mathf.Clamp(mouseMovement[1], -rotClamp, rotClamp), cameraRotation.eulerAngles.z);
How you choose to control that variable is up to the implementation.
Hopefully it can get you started on something that is closer to what you want to achieve.
Of course feel free to ask away! Perhaps you could describe your problem with a picture if these scripts doesn't solve it for you.
Remember to post comments (and not answers), or edit your first post, for further questioning.
Answer by AnimAlu · Jul 19, 2011 at 06:18 PM
Thanks! This gives me a whole new outlook on how this can be done. I can't seem to get it to work on a group of objects simultaneously. I tried placing my group into a new game object, and applying the script to the new game object, but the rotation does not work this way. Any suggestions?
Your answer
Follow this Question
Related Questions
Multiple rotate with mouse 2 Answers
Rotate Player with Camera rotation 2 Answers
Limit Rotations with Min and Max on Mobile 1 Answer
GUI Button Question 1 Answer
Same rotation script affecting different parts of model in different ways. 2 Answers