Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 /
This question was closed Jun 23, 2014 at 12:50 AM by ikelaiah for the following reason:

The question is answered, right answer was accepted

avatar image
0
Question by ikelaiah · May 01, 2014 at 07:28 AM · rotationquaternionrotatetowards

Longest distance rotation problem: From -175 to 175 via 0 using Quaternion.RotateTowards stops at 5, why?

I want to rotate object from 175 to -175 along y-axis via 0 (longest path)

The documentation says "The from quaternion is rotated towards to by an angular step of maxDegreesDelta (but note that the rotation will not overshoot). Negative values of maxDegreesDelta will move away from to until the rotation is exactly the opposite direction."

But I just couldn't make it to do what the documentation says about rotating in opposite direction.

I have this test:

 using UnityEngine;
 using System.Collections;
 
 
 // test of Quaternion.RotateTowards from 175 to -175 via 0 along y-axis
 public class TestRotateTowards : MonoBehaviour
 {
     public float speed = -10;
     
     void Start ()
     {
         // set the object at y = 175
         transform.Rotate (Vector3.up * 175);
     }
     
     void Update ()
     {
         // then rotate towards -175 via 0 using -speed.
         float step = speed * Time.deltaTime;
         transform.rotation = Quaternion.RotateTowards (transform.rotation, Quaternion.AngleAxis (-175.0f, Vector3.up), step);
     }
 }

But the cube jitters when y rotation value is 5 and simply stops there. It never reaches -175, from 175, as I asked it to. Can someone, a quaternion master possibly, shed a light on this?

Comment
Add comment · Show 2
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 robertbu · May 01, 2014 at 07:41 AM 0
Share

RotateTowards() and Slerp take the shortest path between two rotations. In general if you want a rotation of more than 180 degrees, you have to go to something like Vector3.RotateTowards().

avatar image ikelaiah · May 01, 2014 at 07:44 AM 0
Share

@robertbu I'll try Vector3.RotateTowards() approach.

2 Replies

  • Sort: 
avatar image
1
Best Answer

Answer by Scribe · May 01, 2014 at 01:34 PM

Hi there,

It does seem to be a bug with the function, from what I have tested I'm going to make a guess that unity finds the axis that needs to be rotated around using the cross product of the two direction it can get from the Quaternions you supply, however when the quaternions are the inverse of each other, the vectors they represent are on the same line as one another and so the cross product returns a zero vector rather than one perpendicular to the 2 axses.

The way to fix this therefore is have an alternative way of getting the axis it should be rotating around, unfortunately this means supplying an extra parameter, either then axis to rotate around itself or, as I have done below, required the rotation at the begining. Obviously this will therefore still break if the starting rotation is exactly opposite the end rotation so for this eventuality I have simply assumed you want to rotate around the y axis.

Anyway, this code should work if used on its own, I doubt it will work if other rotations are being applied during its progress:

 public float speed = -10;
 Quaternion startRotation;
 Quaternion targetRotation;
 
 float step;
 
 void Start (){
     // set the object at y = 175
     transform.rotation = Quaternion.Euler(Vector3.up * 175);
     startRotation = transform.rotation;
     targetRotation = Quaternion.AngleAxis(-175.0f, Vector3.up);
 }
 
 Quaternion RotateTowards(Quaternion currRot, Quaternion startRot, Quaternion targetRot, float step){
     Vector3 axis = Vector3.zero;
     float angle = 0;
     (Quaternion.Inverse(currRot)*targetRot).ToAngleAxis(out angle, out axis);
     axis = Vector3.Cross((startRot*Vector3.forward), (targetRot*Vector3.forward)).normalized;
     if(axis == Vector3.zero){
         axis = Vector3.up;
     }
     angle = Mathf.Sign(step)*(360-angle);
     angle = angle < 0 ? angle+360 : angle;
     angle %= 360;
     if(angle <= Mathf.Abs(step)){
         currRot = targetRot;
         return currRot;
     }
     currRot *= Quaternion.AngleAxis(step, axis);
     return currRot;
 }
 
 void Update (){
     step = speed * Time.deltaTime;
     transform.rotation = RotateTowards(transform.rotation, startRotation, targetRotation, step);
 }


Hope that helps,

Scribe

Comment
Add comment · Show 1 · 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 ikelaiah · May 01, 2014 at 10:55 PM 0
Share

Accepted as an answer for your clear insight (educated guess and tested it) into the problem.

avatar image
1

Answer by ikelaiah · May 01, 2014 at 10:44 PM

Well, I come up with a rather primitive solution but works. Perhaps someone else have thought of it, but I called it "Aim Half-Way" approach (just invented this a few mins ago). If someone already solved something like this before, please let me know, I'll put a credit here.

The algorithm is like this.

  1. Begin

  2. Find the difference = target angle - target angle.

  3. If the difference > 180, then enter aim half-way mode

  4. Aim Half-way mode:

  5. **Calculate half-way distance = (current + target) 0.5f*

  6. Rotate angle to half-way distance

  7. If the difference of step 2 is still greater than 180, do step 4

  8. Go to final angle destination

  9. End

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

Follow this Question

Answers Answers and Comments

21 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

Related Questions

Quaternion.RotateTowards is inconsistent 0 Answers

Problem finding relative rotation from one quaternion to another 4 Answers

How can I get the rotation between two objects 1 Answer

Rotate object following mouse movement. Object jumps/ flips 1 Answer

How to make a plane face a static but rotating camera? 3 Answers


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