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
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Help with rotation on Z-Axis using EulerAngles

Discussion in 'Scripting' started by nineswordz, Oct 23, 2019.

  1. nineswordz

    nineswordz

    Joined:
    Sep 23, 2019
    Posts:
    12
    Hi, Can someone help with eulerAngles and Quaternions? I made a character moving either left or right continuously using AddForce. When a collision happen, I want it to stop and tilt upwards around 30 degrees from where the player is facing (i.e. a car that crashed and tilt at 30 deg facing the sky from the ground). In this code It works when been hit and facing RIGHT.

    Code (CSharp):
    1. if (isHit == true)
    2.         {
    3.             speed = 0f;                                             // Player stop moving
    4.  
    5.             if (playerLocalScale.x == 1)                            // Facing right
    6.             {
    7.                 tilt = new Vector3(0, 0, degreesTilt);
    8.                 transform.eulerAngles = Vector3.Lerp(transform.rotation.eulerAngles, tilt, Time.deltaTime);
    9.  
    10.             } else { // Facing left
    11.                 tilt = new Vector3(0, 0, -degreesTilt);
    12.                 transform.eulerAngles = Vector3.Lerp(transform.rotation.eulerAngles, tilt, Time.deltaTime);
    13.             }
    But when the player is facing LEFT, the rotation makes a full 360 deg to its designation and it just repeats the rotation infinitely but smoothly because of Lerp. I assume it will work if I put a negative value on the z vale of tilt. but it doesn't work. I also tried putting "-tilt" but still the same. It just rotates in a full 360 degrees. Any help and feedback is appreciated. Thanks
     
  2. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,878
    For a start you dont set eulerAngles directly, you set the rotation using a quaternion.

    So you would want:


    Code (CSharp):
    1. if (playerLocalScale.x == 1)                            // Facing right
    2.             {
    3.                 tilt = new Vector3(0, 0, degreesTilt);
    4.                 transform.rotation = Quaternion.Euler(Vector3.Lerp(transform.rotation.eulerAngles, tilt, Time.deltaTime));
    5.             } else { // Facing left
    6.                 tilt = new Vector3(0, 0, -degreesTilt);
    7.                 transform.rotation = Quaternion.Euler(Vector3.Lerp(transform.rotation.eulerAngles, tilt, Time.deltaTime));
    8.             }
    That may or may not solve your issue, as quaternions solve a lot of rotation based issues. Try that first and then report back with what happens and will provide more advice based on that.
     
  3. nineswordz

    nineswordz

    Joined:
    Sep 23, 2019
    Posts:
    12
    I used this, when facing Right it works but when facing Left it still not work, it still makes a 360 deg full rotation on Z axis, I think it's not accepting the negative value rotation. Maybe this additional details on my game will help?

    It's a 2D game where the player's sprite is just flipping using a click. I'm not really changing the "forward" of my player (So on runtime, the red arrow is still pointing on the positive X regardless the player is facing/moving left or right). I just move on a negative X when moving Left with a facing left sprite, and a positive X when moving right with a flipped sprite facing right. Should I include a rotation of 180 and -180 deg. on Y while flipping direction?

    EDIT: tried to include a 180 and -180 deg rotation. Doesn't work that way I guess.
     
    Last edited: Oct 23, 2019
  4. nineswordz

    nineswordz

    Joined:
    Sep 23, 2019
    Posts:
    12
    Hi

    It seems that this code:
    Code (CSharp):
    1. if (playerLocalScale.x == -1)                           // Facing Left
    2.             {
    3.                 transform.rotation  = Quaternion.Euler(0,0, -degreesTilt);
    4.             }
    produces the result that I wanted. I removed the Lerp function and it now works when facing on the LEFT. though no lerp is happening ofc. How can I simulate this inside a lerp? Any help is appreciated.
     
  5. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,744
    You can use Mathf.Lerp on the float value itself - create a second float, lerp it towards degreesTilt, and use that in your Euler call.

    If you'd like to know more about Euler angles (and why 95% of the time they're terrible), I wrote an article about that. (The usage in your most recent code is one of the few times it's fine to use Euler angles.)
     
  6. nineswordz

    nineswordz

    Joined:
    Sep 23, 2019
    Posts:
    12
    Can you post a sample code? I'm kinda lost right now sorry, just started coding last month. Not really familiar with Mathf.Lerp. Should i put the Lerp on the float z of the Euler?

    EDIT: I don't know but for some reason its not working:
    Code (CSharp):
    1. transform.rotation = Quaternion.Euler(0, 0, Mathf.Lerp(0f, -degreesTilt, Time.deltaTime));
     
    Last edited: Oct 23, 2019
  7. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,744
    Your "0f" needs to be a stored value that changes slowly.
    Code (csharp):
    1. float currentDegrees = 0f;
    2. void Update () {
    3. ....
    4. currentDegrees = Mathf.Lerp(currentDegrees, -degreesTilt, Time.deltaTime);
    5. transform.rotation = Quaternion.Euler(0,0,currentDegrees);
    You may also want to consider using Mathf.MoveTowards instead, which will produce a more consistent movement rate than Lerp when used in this way.
     
  8. nineswordz

    nineswordz

    Joined:
    Sep 23, 2019
    Posts:
    12
    OMG thank you so much! That lerp assigning, it works perfectly now! :) oh the MoveTowards doesn't work btw, maybe it's not designed on rotations? Anyway I've learned so much on this single thread, thank you also to GameDevCoup for the starter code fix. You guys are awesome. Cheers

    EDIT: I realized that MoveTowards uses different parameters. I might stick to Lerp for now. :)
     
    Last edited: Oct 23, 2019