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

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.

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?