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 /
avatar image
0
Question by S_Darkwell · Oct 12, 2014 at 11:32 PM · quaternionlerpaxiseuleranglesgimbal-lock

Per-Axis (Euler) Rotation Control While Avoiding Gimbal Lock

I am writing a target-following script with numerous per-axis settings. Below is the most distilled example I can provide of the rotation portion:

 private void Rotate()
 {
     var _target = Quaternion.LookRotation(Target.position - transform.position, Target.up).eulerAngles;
     var _next = transform.eulerAngles;
 
     for (var i = 0; i < 3; i++)
         _next[i] = Mathf.LerpAngle(_next[i], _target[i], smoothRotateSpeed[i] * Time.deltaTime);
 
     transform.localRotation = Quaternion.Euler(_next);
 }

In the example above, "smoothRotationSpeed" is a Vector3 that applies a different smoothing value to each axis.

Unfortunately, because I am modifying each axis individually, I am running into Gimbal lock issues. How can one avoid or compensate for Gimbal lock without losing per-axis (euler) control?

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
5

Answer by lordofduct · Oct 15, 2014 at 09:42 PM

My answer from: http://forum.unity3d.com/threads/per-axis-euler-rotation-control-while-avoiding-gimbal-lock.274050/#post-1809878

I can't guarantee this will work. But give it a try. I basically only deal with the euler angles of the rotation between current and target. I adjust how much impact that rotation has, and bring it back to quaternions. Dealing with quats as much as possible.

I generalized the 'FromToRotation' as its own static method. That's because I have my own "QuaternionUtil" class that contains a lot of methods likes this. I'm really annoyed by the lack of methods built into the Quaternion from Unity. They have a FromToRotation to get a quaternion between two vectors, but not between two quaternions. For shame.

Note I also renamed the variables.

 using UnityEngine;
 using System.Collections;
  
 public class GimbalTest : MonoBehaviour {
  
     public Transform _target;
     public Vector3 smoothRotateSpeed;
  
     // Use this for initialization
     void Start ()
     {
    
     }
    
     // Update is called once per frame
     void Update ()
     {
         //var target = Quaternion.LookRotation(_target.position - this.transform.position, _target.up).eulerAngles;
         //var next = transform.eulerAngles;
  
         //for (var i = 0; i < 3; i++)
         //    next[i] = Mathf.LerpAngle(next[i], target[i], smoothRotateSpeed[i] * Time.deltaTime);
  
         //transform.localRotation = Quaternion.Euler(next);
  
         var targetRot = Quaternion.LookRotation(_target.position - this.transform.position, _target.up);
         var delta = FromToRotation(this.transform.rotation, targetRot);
         var deltaEuler = delta.eulerAngles;
  
         for (var i = 0; i < 3; i++)
             deltaEuler[i] = Mathf.LerpAngle(0f, deltaEuler[i], smoothRotateSpeed[i] * Time.deltaTime);
  
         transform.rotation *= Quaternion.Euler(deltaEuler);
     }
  
  
     public static Quaternion FromToRotation(Quaternion start, Quaternion end)
     {
         return Quaternion.Inverse(start) * end;
     }
 }
  
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 S_Darkwell · Oct 16, 2014 at 12:37 AM 1
Share

Your solution worked perfectly. It was practically drag-and-drop! Pasted it into its place, changed _target to Target, and it worked straight away. I truly cannot thank you enough! The elegance and simplicity of your solution certainly illustrates my lack of knowledge about Quaternions.

avatar image Alex_K98 · Feb 22, 2015 at 12:09 AM 0
Share

Nice! Works like advertized. :) Thanks

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

30 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

Related Questions

Rotation Lerp 2 Answers

Rotating on a plane 2 Answers

Rotation of child object is different in play mode 0 Answers

Incrementing Rotation Produces Strange Transform Values 1 Answer

Make Quaternion Slerp happen over a 1 second period 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