- Home /
Misbehavior with Quaternion.Slerp
Hey guys! I need some help over here.
I have this script for a flying plane:
private Vector3 MousePosition;
public float moveSpeed = 20;
void Update () {
if (Input.GetMouseButton(0)) {
MousePosition = Input.mousePosition;
MousePosition = Camera.main.ScreenToWorldPoint(MousePosition);
Quaternion newRotation = Quaternion.LookRotation(transform.position - MousePosition, Vector3.up);
newRotation.x = transform.rotation.x;
newRotation.y = transform.rotation.y;
transform.rotation = Quaternion.Slerp(transform.rotation, newRotation, Time.deltaTime * moveSpeed);
}
}
This script rotates the plane when I click somewhere on the screen. When I click in the front of the plane, rotates normally but the misbehavior appears when I click at rear of the plane, it look at the mouse position but it rotates only the tail of the plane. Also it's not following the mouse, At the middle point of the plane going to the rear it rotates the tail. The problem it's the Slerp or LookRotation? Or something I just passing away without seeing it because I'm really tired.
How I can fix this?
Sorry for any bad spelling. Greetings!
What is the intended consequence of the click? Do you want it to rotate more the higher the click, or make the plane point at it? And what do you mean with rotating only the plane, is it looking at the mouseposition but using the tail for pointing?
The plane need to point at the mouse click position but with the nose. It need to rotate all the way to the clicked position. When I click at rear of the plane it points the position with the tail ins$$anonymous$$d of the nose. Also when I click up of the plane, it not rotate.
Answer by joseques · Mar 08, 2014 at 08:28 PM
After some hours of search in the forums I founded another way to acomplish what I trying to do using eulers but adding some math. It's weird that the other methods don't worked for me but thank you anyways guys!! I used this code:
Vector3 mouse_pos = Input.mousePosition;
mouse_pos.z = 10; //Same as the object
Vector3 transform_ = Camera.main.WorldToScreenPoint(transform.position);
mouse_pos.x = mouse_pos.x - transform_.x;
mouse_pos.y = mouse_pos.y - transform_.y;
float angle = Mathf.Atan2(mouse_pos.y, mouse_pos.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle));
Now I need to smooth the movement, but that I can do it by myself.
Answer by whydoidoit · Mar 08, 2014 at 10:02 AM
You are messing with the x and y components of a quarternion which is undoubtedly not doing what you expect (those are not angles and do not only control rotation in those axes see this: http://unitygems.com/quaternions). You probably want to play with the eulerAngles on the rotation instead. Bear in mind that C# requires you to get the whole vector modify it and put it back again.
var rot = newRotation.eulerAngles;
rot.x = transform.eulerAngles.x;
rot.y = transform.eulerAngles.y;
newRotation.eulerAngles = rot;
But I need to rotate only the z axis of the sprite. That's why I assign the current rotation of X and Y axis to the newRotation X and Y values. How I can assign the eulerAngles with the ScreenToWorldPoint vector ? Or there's another much efficient way?
Use the code I posted which maintains the z rotation as you require.
Ins$$anonymous$$d of what your are doing modifying the x and y elements of the quaternion directly.
It only changes randomly my Z axis rotation between -7 and 7. Is not even moving on the X and Y axis
Yeah perhaps specify the position of the $$anonymous$$ousePosition.z per Bunny's answer below.
Answer by Bunny83 · Mar 08, 2014 at 10:06 AM
Your problem are those two lines:
newRotation.x = transform.rotation.x;
newRotation.y = transform.rotation.y;
The x,y,z,w values of a quaternion are not angles. A quaternion is quite complex. You shouldn't mess around with it's individual values since the whole quaternion is normalized and consists of an axis and a rotation.
If you want to limit the rotation to one axis, just make sure your direction is in the same plane. Since it seems to be a 2d game i guess the x-y-plane? in this case you just need to set the z value of the two vectors to the same value. Something like this:
MousePosition = Input.mousePosition;
MousePosition = Camera.main.ScreenToWorldPoint(MousePosition);
MousePosition.z = transform.position.z;
Quaternion newRotation = Quaternion.LookRotation(transform.position - MousePosition, Vector3.up);
transform.rotation = Quaternion.Slerp(transform.rotation, newRotation, Time.deltaTime * moveSpeed);
Since we don't know the exact coordinate system of your world / airplane we can't tell you the exact solution.
Now it's actually looking at the mouse but only with the X axis. It rotates my plane on the Y and Z axis to 90/270 while I move the mouse. I not made any changes to the coordinates, I just dragged the sprite to the Scene.
@bunny83 I normally update the z coordinate before calling the point conversion. Is that just necessary in 3d though?
Your answer
Follow this Question
Related Questions
LookRotation Vector3 is Zero, Yet Slerp Still Rotates? 2 Answers
Slerp to make the right/left side face another object 2 Answers
Rotating about and only one axis 1 Answer
Quaternion.Slerp with Quaternion.LookRotation causes unexpected results 1 Answer
Quaternion LookRotation/Slerp Axis Lock 3 Answers