Hey there,
I am fiddling around with a little Mario Kart like game in Unity. Currently, I am working on the car controller. I don’t use Wheel colliders whatsoever, just a simple car model with a Rigidbody and Box Collider attached.
I managed ac/deceleration including the car to stop after a certain time (if no input by the user). However, I still can’t figure out how to handle the steering.
What I want to achieve:
- Only steerable when velocity != 0, so only while moving forward/backward
- No or very little drag when turning
- Steering when driving backwards
Basically, this is what I am looking for:
My code until now:
##########################
using UnityEngine;
using System.Collections;
public class kartcontrol : MonoBehaviour {
private Rigidbody rb;
private float inputX = 0.0f;
private float inputY = 0.0f;
public float currentSpeed = 0.0f;
public float maxSpeed = 20f;
public float acceleration = 10f;
public float maxReverseSpeed = 10f;
public float deceleration = 5;
public float smoothStop = 5f;
public float steeringAngle = 25f;
private float velo;
Quaternion targetRotation;
void Start()
{
rb = GetComponent();
targetRotation = Quaternion.identity;
}
void Update()
{
inputX = Input.GetAxis(“Horizontal”);
inputY = Input.GetAxis(“Vertical”);
}
void FixedUpdate()
{
if (inputY > 0)
{
// forward
if (currentSpeed < maxSpeed)
{
currentSpeed += acceleration;
}
}
else if (inputY < 0)
{
// backward
if (currentSpeed > -maxReverseSpeed)
{
currentSpeed -= deceleration;
}
}
else
{
// Stopping the car when no user input given
var velocity = rb.velocity;
var localVel = transform.InverseTransformDirection(velocity);
currentSpeed = Mathf.SmoothDamp(currentSpeed, 0f, ref velo, Time.deltaTime * smoothStop );
}
// Apply currentspeed as rigidbody velocity
rb.velocity += transform.forward * currentSpeed;
Debug.Log(currentSpeed + " — " +rb.velocity);
}
}
############################
Thanks in advance 
It’s going to be rather hard to get car-like behavior while using physics but not using wheel colliders.
I highly recommend Edy’s Vehicle Physics, if you can spend $60 to save you literally hours and hours of time and probably get a better result, too.
If you can’t do that, then please use code tags, and focus on one question at a time.
1 Like
Hey,
the physics look great. But I’m developing it for IOS, so I won’t need them to be that realistic.
My code:
using UnityEngine;
using System.Collections;
public class kartcontrol : MonoBehaviour {
private Rigidbody rb;
private float inputX = 0.0f;
private float inputY = 0.0f;
public float currentSpeed = 0.0f;
public float maxSpeed = 20f;
public float acceleration = 10f;
public float maxReverseSpeed = 10f;
public float deceleration = 5;
public float smoothStop = 5f;
public float steeringAngle = 25f;
private float velo;
Quaternion targetRotation;
void Start()
{
rb = GetComponent<Rigidbody>();
targetRotation = Quaternion.identity;
}
void Update()
{
inputX = Input.GetAxis("Horizontal");
inputY = Input.GetAxis("Vertical");
}
void FixedUpdate()
{
if (inputY > 0)
{
// forward
if (currentSpeed < maxSpeed)
{
currentSpeed += acceleration;
}
}
else if (inputY < 0)
{
// backward
if (currentSpeed > -maxReverseSpeed)
{
currentSpeed -= deceleration;
}
}
else
{
// Stopping the car when no user input given
var velocity = rb.velocity;
var localVel = transform.InverseTransformDirection(velocity);
currentSpeed = Mathf.SmoothDamp(currentSpeed, 0f, ref velo, Time.deltaTime * smoothStop );
}
// Apply currentspeed as rigidbody velocity
rb.velocity += transform.forward * currentSpeed;
Debug.Log(currentSpeed + " --- " +rb.velocity);
}
}
I tried using AddTorque but I didn’t like the way steering worked with that. It felt like I was driving on an icy road due to the drag of the rigidbody. I tried playing with the drag parameter but it just didn’t feel natural.
If you still want to write your own solution, here is starting point to learn about car steering geometry: Ackermann steering geometry - Wikipedia
Original mariokart actually applied velocity in the direction of the camera, not the kart, which gave it’s feel. Newer versions use a model like edy’s vehicle physics though. Which is fine on iOS btw. Stiffer suspension, more torque and a little thrust. I would 100% use wheel colliders for this task on mobile.
Alternatively just roll your own raycast suspension - which is just a stuff spring for raycast.
Yeah, but that sliding-on-ice feel is pretty much inherent in physics until you get really complicated (modeling the wheels, with different friction in one direction vs. the other, etc.). The physics of spaceships or hovercraft-on-ice is pretty simple; of airplanes, a little harder; but ground vehicles are the most complex of all.
Got some cool tanks going in my current game using spring force and raycasts, wasn’t that hard to be honest. I’m thinking that for mobile karts, I could even just use a simple compound shape and no rays at all, just contacts.
For this to be faster than the raycast approach, unity needs to fix the allocation spam of OnCollisionStay. Still no idea why some parts of Unity are horrific.
@hippocoder
Mind sharing the piece of code which handles the steering? I will use a bird’s eye view camera (not 2d, but dynamically floating around the kart) so I will need to handle steering relative to the cart.
I don’t really need physics either, I just thought that that would be the best approach when it comes to handle ac/deceleration. As mentioned, when I add
float rotation = inputX * steeringAngle * Time.deltaTime;
transform.Rotate(0, rotation, 0);
it works but the kart is more sliding than actually steering.
Cheers