Advertisement

Unity 2D car control/move + acceleration and break

Started by July 29, 2023 09:01 AM
1 comment, last by Alberth 1 year, 4 months ago

Greetings !

Currently I am working on a Unity top-down 2D simulator game with a car to drive in the city.
In order to move the car I use this code :

public class car_move1 : MonoBehaviour

{

[SerializeField]

private float speed;

[SerializeField]

private float rotationSpeed;

void Update()

{

float horizontalInput = Input.GetAxis("Horizontal");

float verticalInput = Input.GetAxis("Vertical");

Vector2 movementDirection = new Vector2(horizontalInput, verticalInput);

float inputMagnitude = Mathf.Clamp01(movementDirection.magnitude);

movementDirection.Normalize();

transform.Translate(movementDirection * speed * inputMagnitude * Time.deltaTime, Space.World);

if (movementDirection != Vector2.zero)

{

Quaternion toRotation = Quaternion.LookRotation(Vector3.forward, movementDirection);

transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, rotationSpeed * Time.deltaTime);

}

}

}

The question is, how to separate car rotation with its movement and add an acceleration, and all that by using separate keys. For example , arrow keys , ASDW and joystick on gamepad shall rotate, and 2 other keys will accelerate/move and break/stop the car (to be accurate let's take left and right triggers on gamepad).

By this post/message I'm not requesting/asking for a direct code, but if you please direct me, my thoughts to find out the solution.

Thank you

Speed affects the amount of changing position (per time unit). Likewise, acceleration affects the amount of changing speed (per time unit).

So you apply the amount of acceleration to update speed, and apply the amount of speed to update position.

The amount of acceleration is controlled by the throttle and the brake (physically they create forces that work on acceleration).

To avoid infinite speeds, the simple way is to limit speed to some maximum value. A more realistic solution is to add air-drag. It's the force that a moving object experiences because it has to move the air in front of it out of the way. This force gets “subtracted” from the force of the throttle (ie the faster you want to go, the more air you must move out of the way, the strong er the counter-force of the throttle, so you must give more throttle just to keep driving the same speed.) The air-drag grows quadratically iirc (it starts at 0 with 0 speed, but grows faster as speed increases), so at some point the drag counter-froce becomes equally large to the maximum force of the throttle and you're driving at max speed.

As for rotation, there is a distance between the front and the back wheels, and there is an angle in direction between both. This means a car drives in a circle, where the radius of the circle changes if you turn the wheel.

cra turning

Simplistically, the car turns around the the crossing point of the orthogonal lines extended from the tires. In reality the right side front tire must turn less then the left side front tire, or the crossing point of both sides are not at the same spot. You can likely ignore such problems though until you want to make it more realistic ?

As for your code, do keep in mind that floating point computation results are **mostly** an approximation rather than an exact value. This means that comparisons like “if (movementDirection != Vector2.zero)” may not do what you think it does. You test for a one specific value here, but the computations may give you a value “near” it (off by 0.0000000000001 for example), so the test fails since **exactly** 0.00000000000 is not the same as 0.0000000000001 even though you may want to consider the latter value also as “0”. The point to take away here is to test for a range (eg “if vector length < 0.0001 then …”)

This topic is closed to new replies.

Advertisement