- Home /
Vector3 precision issue?
What I want to do is reverse the rotation on my object until it is facing in the opposite direction to its movement (basically, turn the thing around so it's looking at the space it's passing) and then stop the rotation. Now, this code does work in terms of returning the correct values, as demonstrated by the print line's output to the log, but the 'if' statement never fails to run, even if the values match. I'm assuming there's some kind of extra precision used on the internal values which is clipped when sending the numbers to the log. If that's the case, how do I get a match for these values? I can't use mathf.round without first multiplying by 10 (which seems like overkill) since these values lie between -1.0 and 1.0. Is there another way?
playerdir=transform.forward; // Set on AddForce to grab direction of movement
if(Input.GetAxis("Vertical")<0) { // Down key if (transform.forward!=Vector3(0-playerdir.x,0,0-playerdir.z)) { transform.Rotate (0,0-(rotationspeed*Time.deltaTime),0); print(transform.forward+" "+Vector3(0-playerdir.x,0,0-playerdir.z)); } }
Answer by Eric5h5 · Jun 02, 2010 at 09:20 AM
Print the individual X/Y/Z elements of the Vector3 to see what they are without the rounding you get when printing the entire thing. It's almost impossible that the transform.forward would exactly equal the Vector3 that you're comparing it to; try using a range instead.
However, it doesn't seem like that would actually work anyway; if you use
var wantedRotation = Quaternion.LookRotation(-rigidbody.velocity);
then that would give you a rotation of the opposite direction of movement, which you could then rotate towards with Quaternion.Slerp.
Edit: like this...
if (Input.GetAxis("Vertical") < 0.0) {
var wantedRotation = Quaternion.LookRotation(-rigidbody.velocity);
var angle = Quaternion.Angle(wantedRotation, transform.rotation);
var t = (1.0/angle) * Time.deltaTime * rotationSpeed;
transform.rotation = Quaternion.Slerp(transform.rotation, wantedRotation, t);
}
Thankyou, that certainly flips the ship around to face the right way, but it does it instantly. How can I match the speed of this rotation to my rotationspeed variable, based on time? That's why I was trying to do it the way in the code above, because my object has a set rotation speed and the user can let go of the key at any time and the rotation should stop wherever it is. Slerp doesn't seem appropriate for that.
@Cap: You can use Quaternion.Angle(wantedRotation, transform.rotation)
to get the difference in degrees between the current rotation and the desired rotation, and then use that in Quaternion.Slerp to rotate by a constant rate.
I really don't think I can use slerp for this, but I managed to stumble around until I found a solution that works reliably, if not particularly efficiently. There's a buffer of 2 but that's fine for my needs. Gonna stick it in an answer below.
Answer by Cap · Jun 02, 2010 at 09:01 PM
Found a solution that works for me. This lets me turn the ship using its rotation speed value measured over time, letting go of the key stops the rotation, and it picks the shortest route when deciding which way to turn. The 2 variance was necessary to overcome the thing skipping right over 180 but it's more than accurate enough.
playerdir=transform.rigidbody.velocity; // record vector of movement
if(Input.GetAxis("Vertical")<0) { // reverse if(Mathf.RoundToInt(Vector3.Angle(playerdir,transform.forward))<178) { // 2 variance rotation = rotationspeed*Time.deltaTime; var angle1 = Vector3.Angle(transform.right, playerdir); var angle2 = Vector3.Angle(-transform.right, playerdir); if(angle1>angle2) { // find shortest route left/right transform.Rotate (0,rotation,0); } else { transform.Rotate (0,0-rotation,0);
} } }
You definitely can use Slerp; see the edit to my answer for what I meant.
Well I still haven't got my head around Quaternions so I have no idea why or how your code snippet works. It's almost certainly more efficient than $$anonymous$$e tho, so I'll use it anyway. Thanks :)
@Cap: Actually you don't have to understand quaternions to understand that code, which is good because otherwise I couldn't have written it. ;) Basically it's saying "I want a rotation that's the opposite of my velocity. This angle is the difference between my current rotation and the wanted rotation. Now interpolate between my current rotation and the wanted rotation, where the amount of interpolation this frame depends on the angle." The quaternions are kind of a black box; as long as you understand lerp, then the quaternions don't really matter.
Well, I still have a long way to go when it comes to the mathematical side of things. I'm sure I'll be in at the deep end when it comes to writing the AI for all the other ships flying around; that'll probably bring some clarity :)
Your answer
Follow this Question
Related Questions
Object wont rotate in the opposite direction 1 Answer
unknown axis of rotation 1 Answer
Setting Up Vector and Still Rotating the Character 1 Answer
How to prevent Z axis rotation ? 0 Answers
Rotating Transform Evenly 1 Answer