Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • 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
0
Question by Odd-Awter · Apr 27, 2019 at 02:31 AM · rotationvector3quaternionangles

How Do I accurately rotate a player 180 degrees about the Z axis?

So I am working on a gravity altering game that has forced me to better understand how angles work, although I am still struggling. In my game, I want to give the player the ability to flip gravity on demand. (Gravity is manually coded in, it is just a force being constantly applied to vector3.down). However, my issue isn't with gravity, it is with accurately rotating the player 180 degrees. I also have to keep in mind that I plan on the player being able to walk on walls, meaning their rotation may not be strictly 0, 0, 0 or 0, 0, 180 (My current rotation function rotates the player along the Z axis). Basically, if the player was in a cube, the player could be standing on any surface within the cube. But not any slanted surfaces: all surfaces the player walks on are in iterations of 90 degrees. I have code currently to rotate the player, but it does not work accurately. Here is the code:

 void Update()
 {
     if (Input.GetButtonDown("Flip"))
     {
         StartCoroutine(Rotate(rb.rotation * Quaternion.Euler(0, 0, 180)));
     }
 }

 IEnumerator Rotate(Quaternion target)
 {
     yield return null;

     while (Vector3.Angle(rb.rotation.eulerAngles.normalized, target.eulerAngles.normalized) != 0f)
     {
         rb.MoveRotation(Quaternion.Slerp(rb.rotation, target, .5f));
         yield return null;
     }
 }

So when I call Rotate, I pass in the current rotation already rotated 180 degrees around the Z axis, I just have to get to that point. Then I use the IEnumerator to continue to rotate until the angle between the current rotation and our target rotation is zero (Supposedly). Each time it isn't, use MoveRotation and Slerp to get closer, (this way the movement is more smooth). And it "almost" works. I suspect that Vector3.Angle is not totally accurate, because it always stops rotating barely before its target, with a few decimal points off. I tried adding normalized to the vectors being passed in, and I tried using Quaternion.Angle as well, but nothing seemed to fix the issue. I get the feeling that I should be approaching the problem in a completely different manner, but am not sure. Any help is much appreciated.

Comment
Add comment
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

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by JDelekto · Apr 27, 2019 at 10:20 AM

Your problem could very well be the result of floating point calculations which, BTW, can vary by several decimal places in minuscule amounts. You'll probably never really 0.0f exactly, which is what your while loop is checking.

Consider a couple of approaches: a) if you know which direction (positive or negative) you are approaching, you can use = instead of != in your while statement; or b) you can multiply your float angle value by some tolerance level (like 1000 if you only care about 3 decimal places, for example), truncate the floating point portion and convert to an integer, then compare to zero.

There may be several other approaches, but I think might help you in the short term, because I think in your case, your while() loop is not finding the exact comparison to 0f.

Comment
Add comment · Show 2 · 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 Odd-Awter · Apr 27, 2019 at 10:59 PM 0
Share

I appreciate the help, but I actually solved the issue by back tracking and doing it entirely different. To start off, through some testing, I found that for what I am doing, using either of the .Angle functions wouldn't really work, not only because they aren't totally accurate when it comes to decimal points, but also because of the way it is calculated (0, 0, 0 and 0, 0, 180 would return a 0 difference in angle). So ins$$anonymous$$d of checking if I am at my angle target, ins$$anonymous$$d I just keep track of the amount I have rotated. With this new method, I also needed a new way of rotating, a function that rotates towards an angle ins$$anonymous$$d of rotating the current angle by a certain amount. After finding out that Quaternion.RotateTowards exist, I came up with this:

 public float speed; //Speed of rotation at the start
 public float $$anonymous$$Speed; //Speed that rotation will gradually lerp to

 // Start is called before the first frame update
 void Start()
 {
     StartCoroutine(Rotate());
 }

 // Update is called once per frame
 IEnumerator Rotate()
 {
     Quaternion target = transform.rotation * Quaternion.Euler(0, 0, 180); //store the target angle we are trying to reach
     float amountRotated = 0; //keep track of the amount we have rotated
     while(amountRotated <= 180)
     {
         transform.rotation = Quaternion.RotateTowards(transform.rotation, target, speed);
         amountRotated += speed; //the 3rd parameter is the degrees change, so we can keep track of the amount of rotation by adding it each time
         speed = $$anonymous$$athf.Lerp(speed, $$anonymous$$Speed, .3f); //slowly reduce the speed, so the rotation has a more natural feel, slowing it down towards the end
         yield return null;
     }
 }

And it works just as intended. Thank you for your input though!

avatar image JDelekto Odd-Awter · Apr 27, 2019 at 11:05 PM 0
Share

I'm glad you found a solution that worked for you!

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.

Follow this Question

Answers Answers and Comments

160 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Set rotation based on 1,1,1 style vector? How to convert vector3 to quaternion? 1 Answer

Vector3.SignedAngle wrong direction when crossing the 0 point 1 Answer

calculating looking angle between 2 transforms 0 Answers

How to rotate a quad based on another object's rotation? 0 Answers

Problem with normal snapping and rotations. 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