• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
Question by Cap · Jun 02, 2010 at 08:43 AM · transformvector3rotate

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

Comment

People who like this

0 Show 0
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
Best Answer

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);
}
Comment
Cap
Fuller

People who like this

2 Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Cap · Jun 02, 2010 at 10:52 AM 0
Share

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.

avatar image Eric5h5 · Jun 02, 2010 at 06:07 PM 0
Share

@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.

avatar image Cap · Jun 02, 2010 at 08:57 PM 0
Share

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.

avatar image

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

Comment
Fuller

People who like this

1 Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Eric5h5 · Jun 02, 2010 at 10:43 PM 0
Share

You definitely can use Slerp; see the edit to my answer for what I meant.

avatar image Cap · Jun 02, 2010 at 11:12 PM 0
Share

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 mine tho, so I'll use it anyway. Thanks :)

avatar image Eric5h5 · Jun 02, 2010 at 11:27 PM 0
Share

@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.

avatar image Cap · Jun 03, 2010 at 12:17 AM 0
Share

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

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

No one has followed this question yet.

Related Questions

How to prevent Z axis rotation ? 0 Answers

Rotating Transform Evenly 1 Answer

How do I make gameObject.transform.rotation.z equal to a set float value? 2 Answers

Object wont rotate in the opposite direction 1 Answer

unknown axis of rotation 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges