Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

how to fix gimbal lock caused by RotateTowards ?

Discussion in 'Scripting' started by csmehmetyazici99, Feb 13, 2021.

  1. csmehmetyazici99

    csmehmetyazici99

    Joined:
    Feb 1, 2021
    Posts:
    4
    I have been at this for hours.. Please someone save me.

    I am making a sky glider clone. I have a ball player and when I hold my finger on screen the ball is supposed to spread its wings and glide. This is my code that is in the Update function that gets activated when my finger is on screen.

    playerTransform.rotation = Quaternion.RotateTowards(playerTransform.rotation, Quaternion.Euler(98f, yDeg, 0), 450f * Time.deltaTime);


    -98 is constant and its the pitch axis causing the wings to be (almost) parallel to the ground.

    -yDeg is the yaw causing the player to turn left and right. Its is equal to the swipe value of Input.

    Now I want to tilt the wings so my character looks more realistic when turning left and right, but I can't because of gimbal lock. when I rotate around z axis it's reaction is the same as y axis.

    How do I keep RotateTowards (or something equivalent to it) and fix gimbal lock ?

    or alternatively how do I rotate the character independently of these issues around z axis.

    I have tried parenting an empty game object to my player but because the object doesn't move with my ball the rotation angle gets weird. I have also tried rotating by multiplying Quaternion.AngleAxis() values one by one(I even tried changing order of AngleAxis () multiplications) but I couldn't solve it.

    PS. setting the players rotation by multiplying Quaternion.AngleAxis() values one by one wasn't entirely wrong ,but it still had gimbal lock and other problems where the player would start tilting upwards.
     
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Keep track of your pitch, yaw, roll values separately and rebuild the rotation every frame instead. Then you can control the speed of each one independently as well.

    Code (csharp):
    1.  
    2. pitch = 98f;
    3. yaw = Mathf.MoveTowards(yaw, targetyaw, yawSpeed * Time.deltaTime);
    4. roll = Mathf.MoveTowards(roll, targetRoll, rollSpeed * Time.deltaTime);
    5.  
    6. playerTransform.rotation = Quaternion.Euler(pitch, yaw, roll);
    7.  
     
  3. Stevens-R-Miller

    Stevens-R-Miller

    Joined:
    Oct 20, 2017
    Posts:
    676
    I would use GroZZlerR's suggestion, but this statement interested me:
    How did you encounter gimbal lock while multiplying quaternions?