Joachim Chrapek Joachim Chrapek - 1 month ago 12
C# Question

Unity - same turn radius of an object with different speeds

I have an simple circle that can move with script:

public float speed = 3f;
public float rotationSpeed = 200f;

private float horizontal = 0f;

void Update()
{
horizontal = Input.GetAxisRaw("Horizontal");
}

void FixedUpdate()
{
transform.Translate(Vector2.up * speed * Time.fixedDeltaTime, Space.Self);
transform.Rotate(Vector3.forward * -horizontal * rotationSpeed * Time.fixedDeltaTime);
}


The problem is that I want to keep same turn radius with different speed.
Now when I am increasing speed also turn radius is getting bigger:

like here

How can I do this? Do I have to use some kind of ratio to increase speed and rotationSpeed?

Answer

There are two main ways to approach this. First, you could calculate the differential equation for the rate of change of rotation speed with respect to velocity to keep the radius constant, then solve this for the rotation speed. The second, and perhaps easier way is as follows:

The distance the particle has to travel is constant, assuming a semi circular path, this is equal to pi*r, else, it is (theta/2pi)2pi*r.

Consequently, we can calculate the travel time of the object to be equal to the distance divided by its tangential velocity, giving (pi*r)/V.

Finally, your rate of turn is equal to the 2*pi divided by the time you need the turn to take, which gives R = 2Vpi/pi*r rads^-1. Which cancels down to 2Vr rads^-1.

I'm not certain of the exact details of how to implement it but it would look something like this:

void FixedUpdate()
{
    const int radius = 10;
    rotationSpeed = 2 * speed * radius;
    transform.Translate(Vector2.up * speed * Time.fixedDeltaTime, Space.Self);
    transform.Rotate(Vector3.forward * -horizontal * rotationSpeed * Time.fixedDeltaTime);
}

Although it's almost certainly worth checking my maths as I haven't done this sort of thing for a while.

There is a third significantly less graceful way where you calculate the Vector3 position for many points along the parabola that is your path and move to the next one every FixedUpdate(). You can then just alter the dx such that it is larger for faster velocities and smaller for slower ones. This has the advantage of being very easy to implement, but it totally destroys the physics of the application, if that matters.