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. Dismiss Notice

Euler Angles near zero and rollover

Discussion in 'Scripting' started by thesupersoup, Dec 2, 2021.

  1. thesupersoup

    thesupersoup

    Joined:
    Nov 27, 2017
    Posts:
    70
    I have the following problem:
    upload_2021-12-1_22-45-31.png

    I'm checking the player's previous Y rotation against their current Y rotation, and using the result to drive weapon sway. It's all working fine, except for this odd situation right around 0.0f. Naturally, the Euler Angle won't be negative, so moving -2 from 1 lands you on 359, throwing the result up around 358 for a single frame until the previous rotation variable catches up. This creates an odd stutter in the animation visual as you might imagine.

    This is one of those "took me too long to track down" problems, so while I sleep on it I'm curious to hear other possible solutions and perspectives. How would you handle this edge case to ensure consistent and fluid weapon sway animation as the threshold is crossed? My current thoughts are some sort of check like this:

    Code (CSharp):
    1. float currentYRot = this.transform.rotation.eulerAngles.y;
    2. float prevYRot =  _prevRot.eulerAngles.y;
    3. if( currentYRot >= 310 && prevYRot <= 50 )
    4.     currentYRot -= 360;
    5. else if ( currentYRot <= 50 && prevYRot >= 310 )
    6.     prevYRot -= 360;
    7.  
    8. WeaponAnim.SetFloat( "yRot", currentYRot - _prevRot );
    Please feel free to poke holes in my pseudocode solution as well as suggest your own. That if-else-if doesn't sit well with me, and I'm curious to consider other possibilities.
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    Well first off there's https://docs.unity3d.com/ScriptReference/Mathf.DeltaAngle.html which I believe should let you calculate that difference without having to write any of the weird edge case code you have there.

    Second,
    I simply wouldn't rely on reading the transform's euler angles frame to frame for this calculation (or almost any calculation for that matter) because it does the finicky stuff you mentioned.

    Something like this would be cleanest though I guess:
    Code (CSharp):
    1. Quaternion diff = transform.rotation * Quaternion.Inverse(_prevRot);
    2. float yDiff = diff.eulerAngles.y;
     
    thesupersoup likes this.
  3. thesupersoup

    thesupersoup

    Joined:
    Nov 27, 2017
    Posts:
    70
    Mathf.DeltaAngle is exactly the sort of thing I was looking for. Thank you! I'll dig into your second solution as well, if for no other reason than to gain a better understanding of Quaternion * operations.

    Thanks again!