Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Odd Rotation Behavior

Discussion in 'Scripting' started by vanzandtlg, Apr 30, 2022.

  1. vanzandtlg

    vanzandtlg

    Joined:
    Oct 8, 2020
    Posts:
    5
    1. I have a player character that rotates towards a gameObject tied to mouse position, but only on the y axis. This behavior works great.

    2. Childed to the player character are two lights that should only rotates towards the mouse position on the x axis. This behavior works great --half the time.

    upload_2022-4-29_21-37-35.png


    3.It seems that whenever the world rotation of the lights goes below -90 and above 90, it flips. I've tried to add a case for this, but it didn't seem to work.

    4. Here's my code. I'm not a smart man, so if you see an obvious math issue or a better way of doing this, please let me know.


    Code (CSharp):
    1. void Update()
    2.     {
    3.      
    4.         parentRotation = transform.rotation.y;
    5.         Vector3 dir = target.position - transform.position;
    6.  
    7.         dir.Normalize();
    8.  
    9.         switch (constraint)
    10.         {
    11.  
    12.             case Constraint.None:
    13.                 gameObjectLocation = new Vector3(transform.position.x, transform.position.y, transform.position.z);
    14.                 targetLocation = new Vector3(target.position.x, target.position.y, target.position.z);
    15.  
    16.                 Vector3 direction = targetLocation - gameObjectLocation;
    17.                 Quaternion rotation = Quaternion.LookRotation(direction);
    18.                 transform.rotation = Quaternion.Lerp(rotation, rotation, speed * Time.deltaTime);
    19.  
    20.                 break;
    21.  
    22.             case Constraint.X:
    23.                     rotationX = (Mathf.Atan2(-dir.y, dir.z) * Mathf.Rad2Deg);
    24.                     rotationX = Mathf.Clamp(rotationX, -maxXRotation, maxXRotation);
    25.                     transform.localRotation = (Quaternion.RotateTowards(transform.localRotation, Quaternion.Euler(rotationX, 0f, 0f), Time.deltaTime * speed));
    26.          
    27.                 break;
    28.  
    29.             case Constraint.Y:
    30.                 rotationY = (Mathf.Atan2(dir.x, dir.z) * Mathf.Rad2Deg);
    31.                 rotationY = Mathf.Clamp(rotationY, -maxYRotation, maxYRotation);
    32.                 transform.localRotation = (Quaternion.RotateTowards(transform.localRotation, Quaternion.Euler(0f, rotationY, 0f), Time.deltaTime * speed));
    33.                 break;
    34.  
    35.             case Constraint.Z:
    36.                 rotationZ = (Mathf.Atan2(dir.y, -dir.x) * Mathf.Rad2Deg);
    37.                 rotationZ = Mathf.Clamp(rotationZ, -maxZRotation, maxZRotation);
    38.                 transform.localRotation = (Quaternion.RotateTowards(transform.localRotation, Quaternion.Euler(0f, 0f, rotationZ), Time.deltaTime * speed));
    39.                 break;
    40.  
    41.  
    42.         }
    43.     }
     

    Attached Files:

    Last edited: Apr 30, 2022
  2. Cameron_SM

    Cameron_SM

    Joined:
    Jun 1, 2009
    Posts:
    915
    Please use code tags.
     
  3. vanzandtlg

    vanzandtlg

    Joined:
    Oct 8, 2020
    Posts:
    5
    Sorry about that. Fixed now.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,954
    So that expression is identical to simply writing
    rotation
    . If you are unclear why, go study what a Lerp() of any kind does.

    I'm not really sure what you're trying to do, but if you just want to bank the ship according to angle of turning, develop a function to convert your turn rate into a bank angle.

    Even something as simple as assuming bank angle of 0, except if turning left, then bank angle -20 and right is bank angle +20...

    Now use that bank angle to produce a fresh .localRotation along the axis you want:

    Code (csharp):
    1. visiblePortionOfShipTransform.localRotation = Quaternion.Euler( 0, 0, currentBankAngle);
    If you want to smooth it, use this process:

    Smoothing movement between any two particular values:

    https://forum.unity.com/threads/beginner-need-help-with-smoothdamp.988959/#post-6430100

    You have currentQuantity and desiredQuantity.
    - only set desiredQuantity
    - the code always moves currentQuantity towards desiredQuantity
    - read currentQuantity for the smoothed value

    Works for floats, Vectors, Colors, Quaternions, anything continuous or lerp-able.

    The code: https://gist.github.com/kurtdekker/fb3c33ec6911a1d9bfcb23e9f62adac4
     
  5. vanzandtlg

    vanzandtlg

    Joined:
    Oct 8, 2020
    Posts:
    5
    Thanks for the reply, sorry if my question wasn't clear.

    1. Ship is only supposed to rotate towards the mouse on the Y axis. This behavior works.

    2. Childed to the ship are two lights, that should only rotate on the x axis. This behavior works fine hkaf the time for, but it seems that it flips when the light's world rotation is below -90 and above 90.

    3. I've tried to add a case for that, but it didn't seem to work.