How to make ship rotate based on mouse distance from center of screen.

I am trying to make my spaceship constantly smoothly rotate based on mouse pointer position from screen center. The further it is from center the faster ship should turn (up to a maximum angle speed).

The code below does what I need but its instant and not smooth.

transform.Rotate(rotateX, 0f, 0f, Space.Self);
transform.Rotate(0f, rotateY, 0f, Space.World);

Then I tried to play around transform.Rotate but could not get further. At some point it worked, but jerky.

I then tried following code:

var direction = new Vector3(Input.mousePosition.x * 2 / Screen.width - 1, Input.mousePosition.y * 2 / Screen.height - 1, 1f);
var stepRotate = Vector3.RotateTowards(transform.forward, direction, 0.5f * Time.fixedDeltaTime, 0f);
transform.rotation = Quaternion.LookRotation(stepRotate);

It works smoothly but I can not make a 360 turn this way. And also it looks to complicated for such task.

Code below should work if completed right way. But I have no idea how to calculate Quaternions :(.
And also it slows down turning when I put some test value to Quaternion2 (starts turning fast and slows down close to the targeted angle).

transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion2, 1);

thank you in advance

I enclose one of the micro games in my Kurt Arcade game, which has a missile steadily turning towards you.

Substitute the delta direction for your own mouse-to-ship, and then choose some kind of scaling to convert distance to the maximum rate of turn term.

This is the relevant function from within the package:

    private void UpdateMissile()
    {
        // cartesian distance to player
        Vector3 delta = Player.transform.position - Missile.transform.position;

        // TODO: convert your distance to a turn rate, perhaps with an AnimationCurve
        // MissileTurnRate = develop your function here...

        // what heading is that?
        float DesiredHeadingToPlayer = Mathf.Atan2(delta.y, delta.x) * Mathf.Rad2Deg;

        // are we good enough?
        float AngleError = Mathf.DeltaAngle(DesiredHeadingToPlayer, CurrentMissileHeading);

        // nope, then turn!
        if (Mathf.Abs( AngleError) > AcceptableAngleError)
        {
            CurrentMissileHeading = Mathf.MoveTowardsAngle(CurrentMissileHeading, DesiredHeadingToPlayer, MissileTurnRate * Time.deltaTime);
        }

        // missile turns
        Missile.transform.rotation = Quaternion.Euler(0, 0, CurrentMissileHeading);

        // missile moves
        Missile.transform.position += Missile.transform.right * MissileSpeed * Time.deltaTime;
    }

6041018–652844–MissileTurnTowards.unitypackage (11.3 KB)

Thank you! The problem is its 3d game. Is function above could handle it if completed for 3d?

Good question… I imagine if it does work, then the angle would come from Vector3.Angle(), and you would use Quaternion.RotateToward() in place of the Mathf.MoveTowardsAngle

For some reason Quaternion.RotateToward() does not work as it should. Description says it should rotate by fixed degree (maxDegreesDelta) while it slowes down in the end
transform.rotation = Quaternion.RotateTowards(transform.rotation, q, speed * Time.fixedDeltaTime);

Looks like Quaternion.RotateToward() is working fine. The problem with it slowing down at the end of the move is I used random numbers less then 1 put to q (for example 0.5, 0.5, 0.5, 0,5). If I set q as transform.rotation of some object it works fine.