• 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 Oorlfe · Nov 13, 2015 at 09:29 PM · rotation axis

Mathf.Cos having an issue at 90 and 270. Used with rotation of an object around 3 axis with mouse

Hi,

Thank you in advance for any assistance.

I am using the code below to make a cube rotate around all 3 axes following the position of the mouse when the right button is dragged. When the vertical rotation, around the x-axis, determined by the variable "yDeg" gets to 90 or 270 degrees it stops rotating. Swapping things out, guessing and checking, it only seems to have an issue when I use Mathf.Cos. Mathf.Sin seems to work fine, but of course doesn't accomplish what I need.

It looks like it might be because of a change that occurs when the x axis rotation gets to 90. At 90 the y axis and z axis rotations suddenly adjust 180 degrees. Simply adding 180 degrees in that instance doesn't seem to change the result. How do I deal with this issue?

     private int speed = 12;
     private float friction = .3f;
     private float lerpSpeed = 10.5f;
     private float xDeg;
     private float yDeg;
     private float zDeg;
     
     private Quaternion fromRotation;
     private Quaternion toRotation;
         
     void Update () 
     {
         if(Input.GetMouseButton(1)) 
         {            
             xDeg -= Input.GetAxis("Mouse X") * speed * friction;
             yDeg += Input.GetAxis("Mouse Y") * Mathf.Cos (transform.eulerAngles.y * Mathf.PI / 180) * speed * friction;
             zDeg += Input.GetAxis("Mouse Y") * Mathf.Sin (transform.eulerAngles.y * Mathf.PI / 180) * speed * friction;
     
             toRotation = Quaternion.Euler(yDeg,xDeg,zDeg);
         }
     
         fromRotation = transform.rotation;
         transform.rotation = Quaternion.Lerp(fromRotation,toRotation,Time.deltaTime  * lerpSpeed);
     }
 

Is there an issue with Mathf.Cos or is there something else I'm doing wrong?

Thank you.

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 maccabbe · Nov 24, 2015 at 03:24 AM 0
Share

The issue is most likely that quaternion to euler does not produce consistent results since almost every quaternion has multiple euler representations. For instance (90, 0, 0) is the same as (90, 180, 180). So your calculations might switch from cos(0) to cos(180) because, although the orientation of these two euler angles is identical, the values used to represent this orientation are not identical.

Normally if you wanted to use euler angles for your calculation you should store your own rotation and only use transform.rotation/transform.eulerAngles to output a value. However it doesn't seem that this will work as an easy solution in this case.

Side note: $$anonymous$$athf.Deg2Rad is equivalent and a bit clearer than $$anonymous$$athf.PI / 180

avatar image Oorlfe maccabbe · Nov 24, 2015 at 03:49 AM 0
Share

Thank you for your response.

Can you post a script example of this?

2 Replies

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

Answer by Oorlfe · Jun 12, 2016 at 10:52 PM

Turns out the answer was much simpler.

 {
     void Update () 
     {
         if (Input.GetMouseButton(0))
         {
             transform.Rotate (new Vector3 ((Input.GetAxis("Mouse Y")* 200), (-Input.GetAxis("Mouse X")* 200), 0)* Time.deltaTime, Space.World);
         }
     }
 }
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
avatar image
1

Answer by Thomas-Mountainborn · Nov 23, 2015 at 07:57 PM

The problem does not lie with Mathf.Cos, but with the fact that you're building on transform.eulerAngles. As you aptly noticed, there are some strange things going on with rotation values viewed in euler angles. The Unity documentation also states that you should never build on euler angles incrementally. Instead, rotate the transform with fresh values, as such:

 if (Input.GetMouseButton(1))
 {
     Vector3 rotation = new Vector3();
     rotation.y = -Input.GetAxis("Mouse X") * speed * friction;
     rotation.x = Input.GetAxis("Mouse Y") * speed * friction;
     rotation.z = Input.GetAxis("Mouse Y") * speed * friction;
 
     toRotation *= Quaternion.Euler(rotation);
 }
 
 transform.rotation = Quaternion.Lerp(transform.rotation, toRotation, Time.deltaTime * lerpSpeed);

Comment
Add comment · Show 8 · 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 Oorlfe · Nov 23, 2015 at 08:30 PM 0
Share

Thank you for the response. However, it is not creating the desired rotation around each axis.

I used sin and cos of the euler angles in order to establish how much of the y input should rotate the cube around the x axis and z axis. For example, when the horizontal rotation is at 30 degrees and I give it an upwards vertical input 2/3s of the input should go the the x axis rotation and 1/3 should go to the z-axis rotation in order to make it rotate directly up and back. With your code both are getting 100% of the input all the time, so it veers off course and I can't rotate only around one of those axes, only both. How can I compensate for this without using the euler angle input?

avatar image Thomas-Mountainborn Oorlfe · Nov 23, 2015 at 08:46 PM 0
Share

You can still use your cos and sin functionality the same way, just not by building on your euler angles.

 if (Input.Get$$anonymous$$ouseButton(1))
 {
     Vector3 rotation = new Vector3();
     rotation.y = -Input.GetAxis("$$anonymous$$ouse X") * speed * friction;
     rotation.x = Input.GetAxis("$$anonymous$$ouse Y") * $$anonymous$$athf.Cos(transform.eulerAngles.y * $$anonymous$$athf.PI / 180) * speed * friction;
     rotation.z = Input.GetAxis("$$anonymous$$ouse Y") * $$anonymous$$athf.Sin(transform.eulerAngles.y * $$anonymous$$athf.PI / 180) * speed * friction;
 
     toRotation *= Quaternion.Euler(rotation);
 }
 
 transform.rotation = Quaternion.Lerp(transform.rotation, toRotation, Time.deltaTime * lerpSpeed);

The only difference to your code is that I don't keep a field value of the euler angles which get incremented each frame. I build a new rotation, which can be based off of the current euler angles.

avatar image Thomas-Mountainborn Thomas-Mountainborn · Nov 23, 2015 at 09:55 PM 0
Share

Oh, and I'd appreciate it if you would accept the answer, once everything works to your satisfaction.

Show more comments
avatar image Thomas-Mountainborn · Nov 24, 2015 at 05:34 AM 0
Share

Here is my code in its entirety - it definitely rotates, and keeps rotating. The * in the toRotation line is definitely of importance. If you're not familiar with it, it's used to rotate quaternions by other quaternions. It keeps toRotation updated with the correct value, so it can be used in Quaternion.Lerp().

 public class DragRotate : $$anonymous$$onoBehaviour
 {
     public int speed = 12;
     private float friction = .3f;
     private float lerpSpeed = 10.5f;
 
     private Quaternion toRotation;
 
     void OnEnable()
     {
         toRotation = transform.rotation; //Initialize toRotation.
     }
 
     void Update()
     {
 
         if (Input.Get$$anonymous$$ouseButton(1))
         {
             Vector3 rotation = new Vector3();
             rotation.y = -Input.GetAxis("$$anonymous$$ouse X") * speed * friction;
             rotation.x = Input.GetAxis("$$anonymous$$ouse Y") * $$anonymous$$athf.Cos(transform.eulerAngles.y * $$anonymous$$athf.PI / 180) * speed * friction;
             rotation.z = Input.GetAxis("$$anonymous$$ouse Y") * $$anonymous$$athf.Sin(transform.eulerAngles.y * $$anonymous$$athf.PI / 180) * speed * friction;
 
             toRotation *= Quaternion.Euler(rotation);
         }
 
         transform.rotation = Quaternion.Lerp(transform.rotation, toRotation, Time.deltaTime * lerpSpeed);
     }
 }
 
avatar image Oorlfe Thomas-Mountainborn · Nov 24, 2015 at 07:45 AM 0
Share

Initializing "toRotation" was the difference in making it rotate, but I am still having the same issue as at the start. When rotating vertically, at (90, 0, 0) and (270, 0, 0) it stops rotating vertically.

I copied and pasted the code directly from your code here. It is the only code in the script attached to the cube.

avatar image Thomas-Mountainborn Oorlfe · Nov 24, 2015 at 07:56 AM 0
Share

Well, I don't know what to say. If I copy my code, it keeps rotating in all directions (there's a wobble going on, but that's because of your sin / cos logic), and if I copy your code, the cube stops rotating vertically at 90 and 270 degrees.

Show more comments

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

32 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

Related Questions

Pointing Object in the Direction it is going 1 Answer

Limiting X-Axis rotation to 90 degrees and -90 degrees 1 Answer

object rotation simulation based on other two objects rotation. like changing frequency(anolog) in radio with two knobs 1 Answer

updateUpAxis code error 1 Answer

rotating objects around collider axis 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