Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

Lerp transf.up towards direction WITHOUT gimbal lock?

Discussion in 'Scripting' started by IgorAherne, Dec 2, 2019.

  1. IgorAherne

    IgorAherne

    Joined:
    May 15, 2013
    Posts:
    393
    I have two non-related transforms and wish to smoothly rotate one of them depending on the orientation of the other.

    This can be done with the following code:

    Code (CSharp):
    1. _transfA.rotation =   Quaternion.Slerp(_transfA.rotation, _transfB.rotation,  Time.deltaTime*0.01);

    However, I now wish to only rotate so that transfA.up eventually reaches transfB.up

    And I wish to do that without gimbal lock.
    That is, when the up direction points completely down, I don't want the transformA to start spinning around that axis. I presume it therefore shouldn't use euler angles, but rather some Quaternion trickery.

    It's for a game where I have a spherical planet, and need to orient camera relative to the surface, without the camera going crazy at the north and south pole of the planet.

    How to do it?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,806
    I think you just want to use the .LookAt() mechanism of a transform, but supply the second argument that is the "up" vector to consider for that point on the planet.

    Fortunately for spheres, the "up" vector at any point is simply the normalized position vector!
     
  3. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    IgorAherne likes this.
  4. IgorAherne

    IgorAherne

    Joined:
    May 15, 2013
    Posts:
    393
    Correct, that solves it!

    Code (CSharp):
    1. Quaternion wantedRot = Quaternion.FromToRotation( _transfA.up, _transfB.up );
    2.  
    3. _transfA.rotation =  Quaternion.Lerp(_transfA.rotation,
    4.                                       _transfA.rotation*wantedRot,
    5.                                       Time.deltaTime );
    Thanks m8
     
    Last edited: Dec 2, 2019