- Home /
Problem Rotating up vector of camera to mouse position on screen.
I am working on a control script for a psuedo-aircraft in motion using mouse controls. The center of the screen (Screen.width/2, Screen.height/2) has a crosshair and I have a custom cursor at the mouse position. What I am having difficulty with is rotating the z-axis of the camera/player so that the camera up direction points in the same direction that the mouse is from the center crosshairs. Or, to try to explain more clearly, when the player moves the mouse from the center of the screen over to the top-right corner of the screen, the camera and player objects rotate on the z-axis (only!) so that the top-right corner is now "up" to them. If you put the mouse pointer in the bottom center of the screen, the camera would rotate so that it was upside down (and the up vector of the camera would share the same z rotation as the angle from center of the screen to the cursor). I have the following code:
var mouseX: float = Input.mousePosition.x - Screen.width/2; var mouseY: float =-((Screen.height-Input.mousePosition.y) - Screen.height/2); var mouseAngle:float = Mathf.Atan2(mouseY,mouseX)*Mathf.Rad2Deg; if (mouseAngle <0) mouseAngle+=360;
var airAngle:float = Mathf.Atan2(Camera.main.transform.up.y,-Camera.main.transform.up.x)*Mathf.Rad2Deg; if (airAngle <0) airAngle+=360;
var tempRoll: float = Mathf.MoveTowardsAngle(airAngle,mouseAngle,360); var deltaRoll: float = tempRoll - airAngle; if (Mathf.Abs(deltaRoll) < 5.0) deltaRoll = 0.0; // Rotate transform --------------------------------- transform.Rotate(0,0,-deltaRoll* Time.deltaTime);
This works... but only as long as my camera is facing forwards. As soon as I rotate around the Y axis or X axis, this code doesn't work (the target angle is not correct and the camera does not spin the correct way). I know I'm missing something simple (and the way I'm doing this is killing my framerate!), but I can't seem to get this to work correctly. Any advice would be appreciated!
UPDATE
I still have the same issue, but I've approached it from a better direction (I think). My new code is:
var mouseVector: Vector3 = Vector3(Input.mousePosition.x - Screen.width/2,-((Screen.height-Input.mousePosition.y) - Screen.height/2)); var mouseAngle: Vector3 = mainCam.transform.TransformDirection(mouseVector.normalized); var mechAngle: Vector3 = transform.InverseTransformDirection(transform.up); var moveAngle: float = Vector3.Angle(mechAngle,mouseAngle); if ((mechAngle.x-mouseAngle.x) >0) moveAngle *= -1; Debug.Log(mouseAngle.ToString()+" and "+transform.up.ToString()); Debug.Log(moveAngle);
transform.Rotate(0,0,moveAngle*Time.deltaTime);
It still works fine facing forward on the origin... but as soon as I move anywhere else or rotate the model around the y-axis, I get random rotations.
Answer by The_r0nin · Jun 04, 2011 at 09:16 PM
Finally got it working!!! The script is as follows:
screenVec = Vector3(Input.mousePosition.x - ScreenCenter.x, Screen.height - Input.mousePosition.y - ScreenCenter.y, 0);
var tarAngle: float = (Mathf.Atan2(screenVec.y,screenVec.x) * Mathf.Rad2Deg)+90;
if (tarAngle < 0) tarAngle +=360;
var roll:float = Mathf.DeltaAngle(tarAngle , -transform.eulerAngles.z);
if (roll != 0) {
if (Mathf.Abs(roll) > rollSpeed*Time.deltaTime) roll = rollSpeed*Time.deltaTime*Mathf.Sign(roll);
transform.RotateAround(transform.position,transform.forward, roll);
}
Answer by Statement · Jan 06, 2011 at 08:11 PM
Tl;dr (sorry). But if you want a psuedo aircraft script, try this one out. (Copy from similar answer).
Simple aircraft script.
public class Aircraft : MonoBehaviour { public float flightSpeed = 1.0f; public float yawSpeed = 250.0f; public float pitchSpeed = 250.0f;
void Update()
{
float time = Time.deltaTime;
float yaw = Input.GetAxis("Mouse X") * yawSpeed * time;
float pitch = Input.GetAxis("Mouse Y") * pitchSpeed * time;
transform.Rotate(Vector3.left, -pitch);
transform.Rotate(Vector3.forward, -yaw);
transform.Translate(Vector3.forward * flightSpeed * time);
}
}
You probably want to change flightSpeed a bit in case you find the motion too slow. It should be attached to a camera. It uses mouse controls to fly sort of like an airplane.
I appreciate it! But what I was really looking for was to have the vector from the center of the screen to the mouse cursor describe the rotational orientation of the camera/object, and the distance from the center the amount of pitch. I got a script working that uses the mouse position w/ respect to the center for roll and pitch, but it uses screen higher/lower for pitch and screen left/right for roll. Not what I wanted, but adequate until I can figure it out.
Your answer
Follow this Question
Related Questions
Why my bullet does not rotate via Z axis? 1 Answer
How can I fix this randomly rotating gun to an unknown degrees? 1 Answer
Making a shotgun shooting 45 degrees to the left of the mouse 1 Answer
rotation based on mouse position 2 Answers
Finding the Screen Coordinates of the horizon when camera is rotating? 1 Answer