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

Script that lets me rotate player towards velocity direction only in y axis

Discussion in 'Scripting' started by Darkmyst, Feb 9, 2015.

  1. Darkmyst

    Darkmyst

    Joined:
    Aug 3, 2013
    Posts:
    35
    So, i have recenlty change my Symmetrical spherical player to a semi symmetrical crystal like player who is quite tall. Before the direction the player faced was the direction it was going but now i can't do that as it would just look silly. I just want it to rotate in one axis (i think the y) to face towards where it is going. With my limited knowledge of quaternions i tried to do this but failed, the player seems to sort of rotate all over the place.

    Heres a script that i wrote to try and do this, doesn't work so well:

    1. void FixedUpdate()
    2. {
    3. if(doInput == true)
    4. {
    5. float moveHor = Input.GetAxis ("Horizontal");
    6. float moveVer = Input.GetAxis ("Vertical");
    7. Vector3 movement = new Vector3(moveHor, 0.0f, moveVer);

    8. if(Input.GetButtonDown("Jump") && isGrounded == true)
    9. {
    10. Jump();
    11. }

    12. Move (movement);

    13. if (rigidbody.velocity != Vector3.zero)
    14. {
    15. temp = new Vector3(0 , rigidbody.velocity.y, 0);
    16. Quaternion rotation = Quaternion.LookRotation (temp, Vector3.up);
    17. Quaternion newRotation = Quaternion.Lerp (rigidbody.rotation, rotation, 8 * Time.deltaTime);
    18. rigidbody.MoveRotation (newRotation);
    19. }
    20. }
    21. }
     
  2. meatpudding

    meatpudding

    Joined:
    Jan 28, 2015
    Posts:
    39
    Something like this should be roughly what you want. Depending on the co-ordinates, heading will be the rotation around the y-axis. You might need to multiply by Mathf.Rad2Deg before making the rotation.
    Code (csharp):
    1. float heading = Mathf.Atan2(rigidbody.velocity.x, rigidbody.velocity.z);
    2. Quaternion rotation = Quaternion.Euler(0, heading, 0);
     
  3. Darkmyst

    Darkmyst

    Joined:
    Aug 3, 2013
    Posts:
    35
    I tried out your code and it sort of works, but i'm so confused by it so i made a video about the problem (Sorry for croaky voice i have cold);

     
  4. meatpudding

    meatpudding

    Joined:
    Jan 28, 2015
    Posts:
    39
    The purpose of atan2 is to give you the angle of a right triangle when you know the sides. Using atan2 is preferable to using atan(z/x) because it avoids the case where you divide by zero. The angle value that it returns would be in radians. Depending on your co-ordinates you may need to use atan2(y, x) or atan2(x, z), etc.


    Euler angles are rotations about the x, y, z axes respectively. These are what you are normally using in the editor panel in Unity. Using Euler angles in a script is expecially useful when you want to control rotation about one axis only.



    Unity takes Euler angles in degrees, so if you have a value from a trig function like atan2, you need to convert it from radians. For example
    Code (csharp):
    1. transform.localEulerAngles = new Vector3(
    2.   0f,
    3.   Mathf.Rad2Deg * Mathf.Atan2(x, z),
    4.   0f);
    In your specific case, you have extra rotations on your object and it might be worth making a parent transform so that you have two nested sets of rotations, eg (90, 0, 90) and (0, y, 0).
     
  5. Darkmyst

    Darkmyst

    Joined:
    Aug 3, 2013
    Posts:
    35
    I just sorta clicked how quaternions work a little bit. So just to clarify on the actual code would i do something like this:

    1. Put my player object under a new transform.
    2. Attach this script:

    float heading = Mathf.Atan2(rigidbody.velocity.x, rigidbody.velocity.z) * Mathf.Rad2Deg;
    Quaternion rotation = Quaternion.Euler(0, heading, 0);

    3. Celebrate my success.
     
    Last edited: Feb 11, 2015
  6. Darkmyst

    Darkmyst

    Joined:
    Aug 3, 2013
    Posts:
    35
    Tried that, and it didn't seem to work additionally would rad2deg just be multiplying it by 180?

    Well, actualyl i just lied. It did work but doesn't produce very satisfactory results, there is not any smooth transition between the movement, and when i use lerp it gives strange results.
     
    Last edited: Feb 11, 2015