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

character rotation issue

Discussion in 'Scripting' started by mvii3iv, Sep 14, 2014.

  1. mvii3iv

    mvii3iv

    Joined:
    Jul 20, 2014
    Posts:
    16
    Hi!
    I want to my character follows the direction of the keys "a", "s", "d" and "w" (or the arrow keys), so my character needs to rotate from its angle to the new angle but I can´t figure out how,

    I was following this tutorial which explains what I want to do, but the move of my character is wrong.



    The following images show what happens when I start the game








    In fact the C# script is working, but is giving me a wrong rotation and now I so confused,
    also this is the script:




    usingUnityEngine;
    usingSystem.Collections;

    publicclassHotDogMovement : MonoBehaviour {

    publicfloatturnSmoothing = 15f; //Asmoothingvalueforturningtheplayer.
    publicfloatspeedDampTime = 0.1f; //Thedampingforthespeedparameter

    publicfloath;
    publicfloatv;

    voidFixedUpdate ()
    {
    //Cachetheinputs.
    h = Input.GetAxis("Horizontal");
    v = Input.GetAxis("Vertical");

    MovementManagement(h, v);
    }

    voidMovementManagement (floathorizontal, floatvertical)
    {

    //Ifthereissomeaxisinput...
    if(horizontal != 0f || vertical != 0f)
    {
    // ... settheplayersrotationandsetthespeedparameterto5.5f.
    Rotating(-horizontal, -vertical);
    }

    }


    voidRotating (floathorizontal, floatvertical)
    {
    //Createanewvectorofthehorizontalandverticalinputs.
    Vector3targetDirection = newVector3(horizontal, 0,vertical);

    //Createarotationbasedonthisnewvectorassumingthatupistheglobalyaxis.
    QuaterniontargetRotation = Quaternion.LookRotation(targetDirection, Vector3.up);

    //Createarotationthatisanincrementclosertothetargetrotationfromtheplayer'srotation.
    QuaternionnewRotation = Quaternion.Lerp(rigidbody.rotation, targetRotation, turnSmoothing * Time.deltaTime);

    //Changetheplayersrotationtothisnewrotation.
    rigidbody.MoveRotation(newRotation);
    }

    }


    could you help me please, thank you very much ?
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    Wow, all that is working MUCH harder than you need to, unless I grossly misunderstand what you're trying to do.

    Try this one instead:
    Code (CSharp):
    1. void Update() {
    2.    transform.Rotate(0, Input.GetAxis("Horizontal") * 180 * Time.deltaTime, 0);
    3. }
    See how that works for you, and post back here with your results and what you think the next step might be.
     
  3. mvii3iv

    mvii3iv

    Joined:
    Jul 20, 2014
    Posts:
    16
    JoeStrout Thank you very much for your time!, I am sorry if I was not clear, what I need to do is explained in the next images, basically when I press the w (or a,s,d )key I need that my character rotates wherever the position in where it is and follows that direction, like a top down shooter.





    Thanks for all the help
     
  4. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    Aha! Now I see. OK, the original code is still working much too hard, but we need to work a little bit harder than my previous attempt. :)

    OK, I would approach this in two stages. Stage 1: just get the character to turn instantly to the desired direction. To do that, you just compute what that direction is, and then assign that directly to the transform.rotation, like this:
    Code (CSharp):
    1. void Update() {
    2.     Quaternion dir = null;
    3.     if (Input.GetAxisRaw("Horiontal") < -0.1f) {
    4.         dir = Quaternion.Euler(0, -90, 0);
    5.     } else if (Input.GetAxisRaw("Horizontal") > 0.1f) {
    6.         dir = Quaternion.Euler(0, 90, 0);
    7.     } else if (Input.GetAxisRaw("Vertical") < -0.1f) {
    8.         dir = Quaternion.Euler(0, 0, 0);
    9.     } else if (Input.GetAxisRaw("Vertical") > 0.1f) {
    10.         dir = Quaternion.Euler(0, 180, 0);
    11.     }
    12.     if (dir != null) transform.rotation = dir;
    13. }
    I have probably messed up the mapping from axes to directions; just swap around the 0, 90, 180, -90 until you get the result you want.

    Then, Stage 2 will be to make the character rotate smoothly towards the target angle instead of instantly snapping to it. This will be done by keeping your current rotation and target rotation in properties, and then using Mathf.MoveTowardsAngle to move your current towards the target (but only by so many degrees each frame).

    Why don't you give that a try, and if you're still stuck, post back and we'll help some more!
     
  5. mvii3iv

    mvii3iv

    Joined:
    Jul 20, 2014
    Posts:
    16
    JoeStrout Thank you very much now is working.. this is the code for all who need this kind of movement
    Again thank you very much, very kind of you

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class HotDogMovement : MonoBehaviour {
    5.    
    6.     private float speed = 5f;
    7.     private float turnSpeed = 180f;
    8.     public float turnSmoothing = 15f;
    9.     public Animator anim;
    10.     Quaternion dir;
    11.    
    12.    
    13.     void Start () {
    14.         //transform.rotation = uaternion.Euler(-90, 180, 0);
    15.     }
    16.    
    17.    
    18.     void Update () {
    19.  
    20.         if (Input.GetAxisRaw("Horizontal") < -0.1f)
    21.         {
    22.             dir = Quaternion.Euler(0, 90, 0);
    23.         }
    24.         else if (Input.GetAxisRaw("Horizontal") > 0.1f)
    25.         {
    26.             dir = Quaternion.Euler(0, -90, 0);
    27.         }
    28.         else if (Input.GetAxisRaw("Vertical") < -0.1f)
    29.         {
    30.             dir = Quaternion.Euler(0, 0, 0);
    31.         }
    32.         else if (Input.GetAxisRaw("Vertical") > 0.1f)
    33.         {
    34.             dir = Quaternion.Euler(0, -180, 0);
    35.         }
    36.  
    37.         if (dir != null)
    38.             transform.rotation = Quaternion.Lerp(rigidbody.rotation, dir, turnSmoothing * Time.deltaTime);
    39.  
    40.         //move ();
    41.     }
    42.        
    43.     }
    44. }
     
  6. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    For what it's worth, I don't recommend this sort of abuse of Lerp... the third parameter to Lerp is how far to interpolate from the starting position (which is the first parameter) to the target. Instead, you're passing in the current position as the first parameter, and a constant-ish value for the third parameter.

    This is a common abuse, and works reasonably well as long as your frame rate is high, but it's still an abuse and I've seen it cause much confusion and misbehavior before.

    But, I guess if it gets the job done and you're satisfied with it, then no harm done! Good job getting it all put together.