How to make rotation happen over time, preferably smoothly?

At present, I am attempting to build a method of rotation for a player controlled ship in a space-themed game. I have experimented with a number of different systems for making the ship rotate on x and y axes using the WASD keys, but all have had their flaws. The current system i’m using acts with the Quaternion.LookRotation function, and achieves the player object actually moving 360 degrees on both axes, something that it didn’t do before.

However, when tapped, the object moves sharply at 90 degree angles, and spins incomprehensibly when the key is held down. Furthermore, there’s no smoothness to this, something that some other systems i’ve tried, despite other issues, managed to do (Quaternion.Slerp was one such system, and i’d actually rather try that if I could get it to do the full 360 and keep going).

If anyone has a clear fix for this, even if it’s something simple that i’m missing, i’d be grateful.

EDIT: My code, for reference.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerControl : MonoBehaviour
{

    public bool isMovingX;
    public bool isMovingY;

    public Transform xPos;
    public Transform xNeg;
    public Transform yPos;
    public Transform yNeg;

    public float movementX;
    public float movementY;

    //private float timeCountX;
    //private float timeCountY;

    void Start()
    {
        movementX = 1f;
        movementY = 1f;
    }

    void FixedUpdate()
    {
        if (Input.GetKey(KeyCode.W) == true && Input.GetKey(KeyCode.S) == false && isMovingX == false)
        {
            Vector3 xMoveNeg = xNeg.position - transform.position;
            //timeCountX = movementX * Time.deltaTime;
            Quaternion rotationX = Quaternion.LookRotation(xMoveNeg, Vector3.up);
            transform.rotation = rotationX;
            isMovingX = true;
            StartCoroutine(WaitTimeX());
        }
        if (Input.GetKey(KeyCode.A) == true && Input.GetKey(KeyCode.D) == false && isMovingY == false)
        {
            Vector3 yMoveNeg = yNeg.position - transform.position;
            //timeCountY = movementY * Time.deltaTime;
            Quaternion rotationY = Quaternion.LookRotation(yMoveNeg, Vector3.up);
            transform.rotation = rotationY;
            isMovingY = true;
            StartCoroutine(WaitTimeY());
        }
        if (Input.GetKey(KeyCode.S) == true && Input.GetKey(KeyCode.W) == false && isMovingX == false)
        {
            Vector3 xMovePos = xPos.position - transform.position;
            //timeCountX = movementX * Time.deltaTime;
            Quaternion rotationX = Quaternion.LookRotation(xMovePos, Vector3.up);
            transform.rotation = rotationX;
            isMovingX = true;
            StartCoroutine(WaitTimeX());
        }
        if (Input.GetKey(KeyCode.D) == true && Input.GetKey(KeyCode.A) == false && isMovingY == false)
        {
            Vector3 yMovePos = yPos.position - transform.position;
            //timeCountY = movementY * Time.deltaTime;
            Quaternion rotationY = Quaternion.LookRotation(yMovePos, Vector3.up);
            transform.rotation = rotationY;
            isMovingY = true;
            StartCoroutine(WaitTimeY());
        }
        if (Input.GetKey(KeyCode.W) == false && Input.GetKey(KeyCode.S) == false)
        {
            movementX = 1f;
        }
        if (Input.GetKey(KeyCode.A) == false && Input.GetKey(KeyCode.D) == false)
        {
            movementY = 1f;
        }
    }
}

In your Update method:

transform.RotateAround(transform.position, AXIS, rotationSpeed * Time.deltaTime);

For fluid motion, I would advise against directly rotating the ship according to keypresses. Instead, I would suggest modifying a target rotation based on input (eg: Quaternion targetRot) then modifying that target every frame based on your input. Also, instead of using Input.GetKey, consider using Input.GetAxis. This will give you more precision with devices like gamepads, as well, the built in smoothing will make your keypresses give smoother input. This way, on every frame your input can adjust the desired target without fear of jerky motion. Finally, at the end of your update loop, lerp the current rotation towards the target rotation transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, Time.deltaTime * smoothingSpeed; (smoothing speed lets you control how fast the ship rotates towards the target).


if you’re looking for another solution, you could also let physics take the wheel by making your ship into a rigidbody, and control it by adding forces.