- Home /
Quaternion.LookRotation and Vector3.SmoothDamp Problems
Hello,
I have a problem with my rotation script. I am using Vector3.SmoothDamp to rotate my space ship smoothly to face a target that I get through Quaternion.LookRotation.
But it's turning to the right most of the time, even when the target is on the left. Sometimes it works and the ship is turning to the left.
Currently I'm only using this on the y-axis, when I try to do this in 3D-space, everything bugs around.
Following is called in FixedUpdate:
targetRotation = Quaternion.LookRotation(moveTarget - this.transform.position).eulerAngles;
this.transform.rotation = Quaternion.Euler (Vector3.SmoothDamp(this.transform.rotation.eulerAngles, targetRotation, ref rotationVelocity, type.rotationAcceleration, type.maxRotationSpeed));
Reading eulerAngles is problematic. And pulling a certain axis out to manipulate is more problematic. The problem is that for any given rotation, there are multiple eulerAngle representations, and, because the value of eulerAngles is derived from transform.rotation, the eulerAngles you read will change. A couple of questions:
Are you trying to rotate around the local 'y' axis or the world 'y' axis?
Is the object being rotated axes aligned or at an arbitrary angle?
Thanks for your answer,
I am trying to rotate in global because I am using eulerAngles, not localEulerAngles.
It has to work on an arbitrary angle too, I am leaning it on the z-axis while it is rotating.
I thought about handling the rotations myself and set them at the end, but this won't work when using a rigidbody.
Would it work to use the cross-product of the two vectors to get the axis to rotate on?
I'm still very fuzzy on your goal here. The common solution to confine a LookRotation to a particular axis, is to project the look point onto a plane define by the axis of rotation. This is much easier done when you are using a world axis for rotation. For example, if you wanted your object to only rotate around the world 'y' axis you could do:
var dir = moveTarget - transform.position;
dir.y = 0.0;
targetRotation = Quaternion.LookRotation(dir);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
...where 'speed' is a variable you define and initialize. Start 'speed'with a value of 4.0.
This solution won't work for me, there are several problems.
Slerp is doing it over time, it will take the same time to rotate 20 degrees and 60 degrees. But I want it to rotate on a fixed speed, this speed has to increase over time to a maximum, while auto-breaking to not overshoot.
The second thing is that I need it in 3D space, but my ship is only allowed to rotate between -10 and 10 in both x and z axes.
It is moving to the target when the angle in degrees between the two rotations is less than 30, the ship is able to move on the y-axis without facing it directly when it's over or under the target.
I know this is quite complicated, but I really need this.
I know from experience that I can only give an accurate answer to a rotation question if I can fully visualize the problem in my head. Right now I cannot visualize what you need.
But I want it to rotate on a fixed speed,
If you want a fixed speed rotation, replace the Slerp() with RotateTowards(), 'speed' then becomes degrees per second.
it will take the same time to rotate 20 degrees and 60 degrees
That's not true. Using (or perhaps misusing) Slerp() in the example code will produce an eased rotation that will take longer for 60 degrees than 20, but it will not be fixed speed, or fixed time.
but my ship is only allowed to rotate between -10 and 10 in both x and z axes.
World or local rotation for x and z? What is doing this rotation and how are you planning on the limits? Is the 'y' rotation you are trying to script world or local?
this speed has to increase over time to a maximum, while auto-breaking to not overshoot.
You are saying 'fixed speed', but now it varies over time. Overshoot from what?
I need a diagram, a video, reference in another game, something to nail down a firm visualization of the problem.
Answer by xPayDay_ · Nov 03, 2014 at 06:27 PM
Thank you very much, but my system fits my needs now :)
Btw. here my code in case someone needs something like this:
targetRotation = Quaternion.LookRotation(moveTarget - this.transform.position).eulerAngles;
Vector3 eulerAngles = this.transform.rotation.eulerAngles;
eulerAngles.x = Mathf.SmoothDampAngle(eulerAngles.x, targetRotation.x, ref rotationVelocity.x, type.rotationAcceleration, type.maxRotationSpeed);
eulerAngles.y = Mathf.SmoothDampAngle(eulerAngles.y, targetRotation.y, ref rotationVelocity.y, type.rotationAcceleration, type.maxRotationSpeed);
eulerAngles.z = Mathf.SmoothDampAngle(eulerAngles.z, targetRotation.z, ref rotationVelocity.z, type.rotationAcceleration, type.maxRotationSpeed);
this.transform.rotation = Quaternion.Euler (eulerAngles);
Your answer
Follow this Question
Related Questions
Slerp to make the right/left side face another object 2 Answers
Need help with rotation 4 Answers
LookRotation Vector3 is Zero, Yet Slerp Still Rotates? 2 Answers
Turret rotation on one axis problems 2 Answers
Rotating about and only one axis 1 Answer