4
\$\begingroup\$

I'm pretty sure I need to use the Quaternion.Lerp although I don't know how, my character already rotates but it's instantly, which is pretty unrealistic and not smooth. I'm extremely new with Unity (I just started 2 days ago), so I think asking here is a good idea since I will get help from people with experience:

private Rigidbody rb;

void Start()
{
    rb = GetComponent<Rigidbody>();
}

void Update()
{
    //Character Rotation        
    {
        if (Input.GetKey(KeyCode.D))
            rb.transform.rotation = Quaternion.Euler(0, 90, 0);

        if (Input.GetKey(KeyCode.A))
            rb.transform.rotation = Quaternion.Euler(0, -90, 0);

        if (Input.GetKey(KeyCode.W))
            rb.transform.rotation = Quaternion.Euler(0, 0, 0);

        if (Input.GetKey(KeyCode.S))
            rb.transform.rotation = Quaternion.Euler(0, 180, 0);
    }
}
\$\endgroup\$
2
  • \$\begingroup\$ Are you rotating it as part of animation? Or rotating it as part of gameplay, such as in Asteroids? \$\endgroup\$
    – Evorlor
    Jul 3 '19 at 15:06
  • \$\begingroup\$ Part of animation, also this is suppose to be a 3d game \$\endgroup\$
    – Hugo Sousa
    Jul 3 '19 at 15:18
3
\$\begingroup\$

Create a private variable for the desired rotation. This variable represents the direction the object is supposed to face, but might not yet face towards. Have key input change the value of that variable.

Then use Quaternion.RotateTowards in your update-function to gradually change the actual rotation towards the desired rotation

public float turnSpeed = 200.0f; // adjust to taste in inspector

private Rigidbody rb;
private Quaternion desiredRotation = Quaternion.Euler(0, 90, 0);

void Start() {
    rb = GetComponent<Rigidbody>();
}

void Update() {
    //Character Rotation        
    {
        if (Input.GetKey(KeyCode.D))
            desiredRotation = Quaternion.Euler(0, 90, 0);

        if (Input.GetKey(KeyCode.A))
            desiredRotation = Quaternion.Euler(0, -90, 0);

        if (Input.GetKey(KeyCode.W))
            desiredRotation = Quaternion.Euler(0, 0, 0);

        if (Input.GetKey(KeyCode.S))
            desiredRotation = Quaternion.Euler(0, 180, 0);
    }

    rb.transform.rotation = Quaternion.RotateTowards(
           rb.transform.rotation, 
           desiredRotation, 
           turnSpeed * Time.deltaTime );
}

And by the way, it might be a good idea to not constantly recreate the quaternions but to put them into constants. This improves performance (although only to a negligible amount in this use-case) and makes the code more readable:

private static readonly Quaternion ROTATION_NORTH = Quaternion.Euler(0, 0, 0);
private static readonly Quaternion ROTATION_EAST = Quaternion.Euler(0, 90, 0);
private static readonly Quaternion ROTATION_SOUTH = Quaternion.Euler(0, 180, 0);
private static readonly Quaternion ROTATION_WEST = Quaternion.Euler(0, -90, 0);

/*...*/


if (Input.GetKey(KeyCode.D))
   desiredRotation = ROTATION_EAST;

if (Input.GetKey(KeyCode.A))
   desiredRotation = ROTATION_WEST;

if (Input.GetKey(KeyCode.W))
   desiredRotation = ROTATION_NORTH;

if (Input.GetKey(KeyCode.S))
   desiredRotation = ROTATION_SOUTH;
\$\endgroup\$
0
\$\begingroup\$

From a technical perspective, Quaternion.Lerp is what you want. From a gameplay perspective, you are taking the wrong approach.

Control your character's movement via its position, so that you have good controls. Then animate the character separately, without using physics. (Unless you are using root motion, but that's a different conversation.)

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .