Part 1: Making a Simple Car
Disclaimer: part one was taken from and modified from the base unity 5 tutorials; I felt it was needed as a base to build off of for the rest of the tutorials.
So the first thing we need to do is build a basic car. For this tutorial I will be only using primitives.
1. Create a 3d Plane (GameObject – 3D Object
– Plane)
-Set Position to (0, 0, 0)
-Set Scale to (100, 1,
100)
2. Create Empty Game Object (GameObject –
Create Empty)
-Set Position to (0, 0, 0)
-Rename
to Car
-Add
Component Rigidbody
-Set
Mass to 500 (If to little it will fly away)
3. Now Create a Cube (GameObject – 3D Object
– Cube)
-Set Position to (0, 0, 0)
-Set Scale to (1, 1, 3)
[Forward and backwards will be in the Z axis]
-Rename to CarMesh
-Make the Make “CarMesh”
a child to the Car
4. Create Empty Game Object (GameObject –
Create Empty)(Not Child)
-Rename
to Wheels
-
Make it a child of Car
5. Duplicate Wheels
-Rename
to frontRightWheel
-Add
component Wheel Collider
-Make
it a child of Wheels
-Set
Position to (1, 0, 1)
6. Duplicate frontRightWheel
-Rename
to frontLeftWheel
-Set
Position to (-1, 0, 1)
7. Duplicate both frontRightWheel and frontLeftWheel
-Rename
one to rearRightWheel
-Set
Position to (1, 0, -1)
-Rename
one to rearLeftWheel
-Set
Position to (-1, 0, -1)
8. Move Car above the plane and have Car
selected and press play.
-See
the wheel springs bounce? Now we make the wheels move.
9. Create a new C# script (Right Click – Create
– C# Script)
-Name
it SimpleCarController
10. Add to SimpleCarController
//The
maximum amount of power put out by each wheel.
public float maxTorque = 500f;
//The max distance a wheel can turn.
public float maxSteerAngle = 45f;
//The physics of the wheels, max 20 axels.
//WheelCollider[4] 4 is how many wheels we have.
public WheelCollider[] wheelCollider = new WheelCollider[4];
public void FixedUpdate()
{
//Turn the wheels to a set max, with an
input.
float steer = Input.GetAxis("Horizontal")
* maxSteerAngle;
float torque =
Input.GetAxis("Vertical") * maxTorque;
//Sets which wheels turn, this is the
two front wheels.
wheelCollider[0].steerAngle = steer;
wheelCollider[1].steerAngle = steer;
//Sets which wheels move forward or
backwards.
for (int i = 0; i < 4; i++)
{
wheelCollider[i].motorTorque =
torque;
}
}
Back to Unity
11. Place
SimpleCarController on to Car
frontRightWheel
frontLeftWheel
rearRightWheel
rearLeftWheel
13. Make
the Main Camera a child of Car, place it where you can see the whole
car.
-Press play, you should now be
able to drive around.
Your car may vibrate after
you turn or reach a certain speed. That is because we do not have real wheels,
just the physics of a wheel; so we need colliders for wheel objects.
14. Create
an Empty GameObject (GameObject – Create Empty)
-Name it frontRightWheelObject
-Make it a child of frontRightWheel
-Set Position to (0, 0, 0)
15. Create
a Cylinder
-Set Scale to (1, 0.1, 1)
-Set Rotation to (0, 0, 90)
-Rename to frontRightWheelMesh
-Make it a child of frontRightWheelObject
-Set Position to (0, 0, 0)
It
should now look like this
16. Do
the same for the other 3 wheels following the same naming convention.
-They may be slightly above the
Wheel Collider, just ignore it for now we will fix it in code.
Press
play now, it will no longer vibrate, but the wheels will not be rotating when
you go forward or turn. We must set that up in code.
17. Go
to the script SimpleCarController and add
//Each
wheel needs its own mesh
public Transform[] wheelMesh = new Transform[4];
public void Update()
{
//Sets the wheel meshs to match the
rotation of the physics WheelCollider.
UpdateMeshPosition();
}
//Sets each wheel to move with the physics WheelColliders.
public void UpdateMeshPosition()
{
for (int i = 0; i < 4; i++)
{
Quaternion quat;
Vector3 pos;
//Gets the current position of the
physics WheelColliders.
wheelCollider[i].GetWorldPose(out pos,
out quat);
///Sets the mesh to match the
position and rotation of the physics WheelColliders.
wheelMesh[i].position = pos;
wheelMesh[i].rotation = quat;
}
}
Back to Unity
18. Go to the Car and add the (______WheelObject)’s to the new Table in the code (Wheel Mesh)
-Note they must be in the same
order as the Wheel Collider Table.
-If
you want you can try adding the WheelMesh’s to the table.
19. Press
Play and Test,
-You cannot move
-Access all the WheelMesh’s
and change the Capsule Collider Radius to 0.4
You could not move because
the Capsule Collider was not allowing the Wheel Collider to touch the ground.
20. Add
some ramps and small bumps and watch what happens.
-You may notice your car will
flip and over all act unrealistically.
-This is because your center of
mass is averaged by the ridged body between ALL colliders.
21. Create
Empty Game Object (GameObject – Create Empty)
-Name it CenterOfMass
-Make it a Child of Car
-Set its position to (0, -0.5, 0)
22. Open
the Code SimpleCarController and add:
//If you do not use center of mass the wheels
base it off of the colliders
//By using center of mass you can control where it is.
public Transform t_CenterOfMass;
//Ridged body accessor.
private Rigidbody r_Ridgedbody;
public void Start()
{
// This sets where the center of mass
is, if you look r_Ridgedbody."centerOfMass" is a function of ridged
body.
r_Ridgedbody =
GetComponent<Rigidbody>();
r_Ridgedbody.centerOfMass =
t_CenterOfMass.localPosition;
}
Back
to Unity
23. On
the Car place the CenterOfMass Object in the new slot in the code.
Your
car should now no longer flip as much and over all be more stable.
Key for code
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class SimpleCarController : MonoBehaviour
{
//If
you do not use center of mass the wheels base it off of the colliders
//By
using center of mass you can control where it is.
public Transform t_CenterOfMass;
//The
maximum amount of power put out by each wheel.
public float maxTorque = 500f;
//The
max distance a wheel can turn.
public float maxSteerAngle = 45f;
//Each
wheel needs its own mesh
public Transform[] wheelMesh = new Transform[4];
//The
physics of the wheels, max 20 axels.
//WheelCollider[4]
4 is how many wheels we have.
public WheelCollider[] wheelCollider = new WheelCollider[4];
//Ridged
body accessor.
private Rigidbody r_Ridgedbody;
public void Start()
{
//
This sets where the center of mass is, if you look
r_Ridgedbody."centerOfMass" is a function of ridged body.
r_Ridgedbody = GetComponent<Rigidbody>();
r_Ridgedbody.centerOfMass = t_CenterOfMass.localPosition;
}
public void Update()
{
//Sets
the wheel meshs to match the rotation of the physics WheelCollider.
UpdateMeshPosition();
}
public void FixedUpdate()
{
//Turn
the wheels to a set max, with an input.
float steer = Input.GetAxis("Horizontal") * maxSteerAngle;
//Move
forward or backwards based on the maxTorque, with an input.
float torque = Input.GetAxis("Vertical") * maxTorque;
//Sets
which wheels turn, this is the two front wheels.
wheelCollider[0].steerAngle = steer;
wheelCollider[1].steerAngle = steer;
//Sets
which wheels move forward or backwards.
for (int i = 0; i < 4; i++)
{
wheelCollider[i].motorTorque = torque;
}
}
//Sets
each wheel to move with the physics WheelColliders.
public void UpdateMeshPosition()
{
for (int i = 0; i < 4; i++)
{
Quaternion quat;
Vector3 pos;
//Gets
the current position of the physics WheelColliders.
wheelCollider[i].GetWorldPose(out pos, out quat);
///Sets
the mesh to match the position and rotation of the physics WheelColliders.
wheelMesh[i].position = pos;
wheelMesh[i].rotation = quat;
}
}
}