Hello everyone and welcome to another video
about Godot. A couple of weeks ago an issue was raised
around the vehicle physics implementation in Godot 3.0. I decided to port the truck town demo to Godot
3 to try this out and while it works it is outdated and indeed showed some problems. To get a better understanding I've been working
on a new demo, an early preview of which is playing in the background. While the demo is far from ready I thought
it would be a good idea to make a short tutorial on setting up a car simulation in Godot. There are a few issues left, hopefully these
will be resolved in the not to distant future. First lets look at a few resources that we
can use. HDRIHaven is a great site that provides free
HDRI textures that we can use for our sky. Textures.com is another great site where we
can source a few textures we will need. Next we have the Kronos GLTF exporter for
Blender. GLTF is a new data format for 3D files. While new and still needing some tweaks I
have found that the export and import process work quite well. Note the instructions within the scripts subfolder
that you need to follow to install this plugin in Blender. The car we’ll be using I’ve obtained from
turbosquid. Another great site where you can download
both free and paid meshes of generally high quality. Finally I want to give a shout out to Clelio
Rossi, while I’m not using any of his assets in this tutorial he provided the great race
track you saw in the intro video. I have already created the project in Godot
and inside of this I have created an assets folder. Within this folder there is already a textures
folder that contains a few textures that we will use. We are going to edit the default environment
and change our background to use a panoramic sky map. We can assign the texture we downloaded from
HDRI haven here. By setting this up in our default environment
we will have this map as the default in any scene we edit. For now we are going to create a very simple
scene. We will just create a floor that interacts
with our physics engine. For this we first create a static body. We add a collision shape to this with a plane
as a collider. And we add a MeshInstance with a plane mesh. We’ll make this plane mesh nice and large,
subdivide it a little and apply a texture so can we actually see the ground move as
our car drives over this surface. We’ll rename a few things. I’m also adding a directional light to simulate
the sun. While our scene is lit indirectly through
our sky this allows us to cast a proper shadow on the ground. To make this looks nice I attempt to align
the light with the sun in our image and finally turn shadows on. Here I’m adding a placeholder node for our
car. We’ll do this differently in a future video
but for now this will do. We also need to add a camera to our scene. The placement of our camera doesn’t matter
much right now. We will move it a little backwards. We will do more with the camera later on. And finally we save our scene and quickly
test if it all works. Before we open up blender we’ll add a folder
to place our car files in. In our assets folder we first create a folder
called Cars and then a folder called Caterham. We clear out Blenders default cube and camera. We leave the light so our scene is lit. Then we import our car into our scene. I have downloaded the FBX version of the car,
that gave me the best results on import. Note that most of the materials have not come
across. The car looks pretty bland at the moment. We will correct that once the car has been
successfully imported into Godot because we have access to the PBR settings there. There is one problem with our mesh that we
need to fix before we can export it to Godot. Note that all four wheels are part of the
same object. We will have to split them apart. I am going to hide all the other objects to
make my life easier. After selecting the wheels object we press
TAB to go to edit mode. Press A to deselect all vertices. Now we can use B to select all the vertices
that belong to one of the wheels. Blender has only selected the visible vertices
and not the ones hidden at the back. Use this little icon in the toolbar to make
Blender select hidden vertices as well and try again. We can now use P to move this wheel into its
own object. Lets fast forward repeating this for two more
wheels. This will leave the last wheel as part of
our original object. Then press tab to exit edit mode. Next lets rename all our wheels so we can
tell them apart. Now that all the wheels are split into their
own objects we notice a new problem. Each wheel still has their origin point set
to the original origin position. We need to centre the origin point of each
wheel to the centre of each wheel. To do this we select a wheel, press tab to
go into edit mode and select a vertices at the centre of the wheel. Press Shift-S to move the 3D cursor to the
position of the selected vertice. Now press tab to exit edit mode and press
Shift-Control-Alt C to move our origin point to our 3D cursor. If we had more time we could probably find
a better vertice to use or tweak our new origin point afterwards but this will do for now. We need to repeat this for our other 3 wheels,
as this is more of the same I’ll fast forward through that process as well. At the end of this we can unhide all our other
objects. Just in case we need to do more changes later
on we’ll save our project as a blend file. Now we are ready to export our Caterham as
a GTLF file which we will save in the assets folder of our Godot project. Now it is time to return to Godot. In Godot we can see that Godot immediately
starts processing our GLTF file. In the background it converts the GLTF file
to a format Godot can handle and it creates material files for each material in our GLTF
file. I did have to manually copy a number of textures
that didn’t come across automatically and for some reason I ended up with both a jpeg
and png version of the speedo. Lets take a look at our GLTF file by double
clicking on it and choosing new inherited. When we examine the scene that Godot imported
a little closer we notice that we suddenly have VehicleWheel nodes added to our scene. Now remember that when we were in Blender,
we had to split the wheels out into separate objects and adjust their origin points. This is definitely not something we’ve set
up in Blender. Either the GLTF export or GLTF import latches
on to something and decides to adds these physics nodes to our scene. If anyone knows what triggers this, please
let me know in the comments. I think this is a very cool feature, if this
didn’t happen we would have had to save our wheels into separate files and build this
scene tree ourselves. We do however see that there are some problems. Note the yellow triangles in the scene tree
that indicate something is not correctly setup. When we look at the message Godot gives us
it tells us that the VehicleWheel nodes must be child nodes of a VehicleBody but the root
note of our scene is a Spatial. This is easily correct by selecting our GLTF
file and going to the import tab. On this tab we can change the type of node
the import will use for its root node and we can set this to VehicleBody. I’ll also change the name of the tab. After this we can simply press Reimport to
apply our changes to the scene being imported. While our scenes root note has indeed changed
the name hasn’t but that is easily rectified by closing and reopening the GLTF file. If we wanted we could use the GLTF file directly
in our project. I’m using the inherit function however because
this allows us to make changes to our scene and Godot will save these changes as overrides. If I would go back to Blender and make changes
to my models and export these changes Godot will reimport the GLTF file and attempt to
keep as many of my changes as possible in tact. We’re going to make our first of such changes. We can see there is still a triangle warning
us of a problem and that is that our car does not have a collision shape. We could select the body of our car and use
the Create Convex Static Body function to do this. Instead I am going to create a very simple
collision shape for our car, just a box that roughly contains the main body of our caterham. I’m keeping this shape conservative for
now because if our collision shape hits the ground when our suspension is not yet setup
correctly, Newtons third law could send our car flying. I’ll probably change this to a better fitting
shape at some point in the future. I’m also quickly turning off our lamp, we
should have deleted this in Blender. One quick thing of note is looking at the
origin point of our VehicleBody. Note that this is on the ground and we got
lucky that the import resulted in this. This point will act as the centre of gravity
of our car and we want this to be nice and low. A higher centre of gravity would lead to the
car easily topple over. As we are about to work on bigger changes
this would be a good time to save our scene. We are going to start working on our material
changes and here the mantra “save often” really goes. It is interesting to note as a look around
our car, only the material used on the dials have retained their texture. I think this is because the other textures
are used as depth maps and that doesn’t come across. I did have some problem using them as depth
maps in Godot so you will not see me doing that in this video but I may revisit this
in the future. The other mystery is that while the materials
have lost their properties somewhere at the start of our pipeline, the preview images
of our materials are correct. The GLTF import will create material files
as it encounters new materials but it will not overwrite existing ones. We can safely tweak the material settings
without fearing they will be overwritten when the GLTF is reimported. Not all the materials have a very useful name. We will have to go through them one by one,
figure out what they are for, and adjust them. I won’t talk about every material in this
video, it took me nearly 30 minutes to set them all up but I’ll pick out a few highlights. Looking at our very first material a handy
way I find to figure out what it is used for is by simply changing the albedo colour. We immediately see the outer wall of our tire
turn red. A simple CTRL-Z will undo our colour change. Our tire right now looks like plastic but
this is easily changed by going to the Roughness settings and turning up the roughness of our
material. This should be a value between 0, not rough
at all, and 1.0 which is matt. One thing that is really important making
these changes is to always save with the button in the resource editor. If you do not save these materials the changes
will revert the next time you open the scene. The next material is called disk material
but it isn’t actually the brake disk, it is the material used for the rim of the wheels. This is a material that we want to make really
metallic so that it reflects its surroundings. Here we change the metallic property in the
metallic settings which works similarly to our roughness setting. A setting of 0 means not metallic at all,
a value of 1.0 makes a very reflective material. I really like these PBR settings. As I was changing the material used for the
exhaust pipe I noticed that you could see through the inside of the pipe. While you have to be careful with this setting
as it can be wasteful I am simply turning off culling on this material. Now we can see the inside of our pipe. For our headlights I’m first updating a
material found a little further in our list and that is the headlight glass material. This is supposed to be a transparent material
but for this to work we first need to turn on transparency and then change the alpha
on our albedo colour. After this has been changed we can update
the material that is used for the inside of our light. This is a material that needs a strong metallic
settings. Now for the material I was really looking
forward to doing and that is our main body colour. Here we simply change the albedo colour to
a nice dark blue and then set the metallic setting to something nice and shiny. The end result I feel is fairly spectacular
especially with the HDRI sky. Another material of note is this material
used with a carbon fibre texture. The texture was lost so we need to reinstate
it but if you look at the source renderings you see that the texture looks to big. We scale up our UV on this material to correct
this and tweak a few of the other settings for effect. The glass material used for the windscreen
was imported without its transparency. For this material we again need to turn on
transparency and set the alpha on our albedo colour. I like to give glass a hint of green for effect. All our materials are now set up but there
are still a few other changes we need to do. For some reason the import process has applied
a scale to our VehicleWheel. This scale should be applied to the mesh of
our wheel. I’m guessing this is an error in the import
but it is easily rectified by setting the scale on our VehicleWheel to 1 and copying
the scale into our wheel meshes. We need to do this for all four tires. This also allows us to correct the radius
of our wheel so that our physics engine knows the correct size of our wheel. In order for us to drive our car we need to
add some logic. Godot takes care of the bulk of everything
but there are still a few things that we need to do ourselves. I’ve prepared the code for this beforehand
so we are going to simply attach this script to our vehicle node. We’ll be extending this script in future
videos but what is important is that the script was written
to be used with different car models. We attach the script to our VehicleBody root
node in our car scene. Let’s have a look
at the code itself. I’m starting a few lines down where you
see that I’m setting up some controller mappings. I’ve added some code in my physics process
that reads out the axis related to these controllers and if needed overrides these values based
on the user using the keyboard for input. Odino has submitted a nice PR that would make
it much easier to set up these types of mappings but we’re doing it ourselves here for now. At the top of the script we define a number
of export variables that control the acceleration, braking and steering behaviour of the car. These will be different for different cars
so this allows us to set these up. We also have two variables that we use to
smooth out our steering input. Further down our script we can see how we
apply these values. Our engine force and brake value are directly
determined by multiplying our controller input with our maximum values. In the intro at the start of this video you
could see that I’ve expanded on that greatly with support for shifting through gears but
we’ll leave that for another video. There is a little bit more code for steering. We start by calculating a target value based
on our controller input and then update our actual steering angle based on our maximum
move speed. Here we can see on our car node that we can
set our export variables to tweak them specifically for this car. Let’s go back to our main scene and load
in our car scene so it becomes part of our game. I have also prepared a very simple script
to animate our camera so lets load that in as our camera script. This script has our camera follow an object
that you can set using the follow_this_path variable. It has a variable that determines how far
away the camera should be and a variable that determines how high the camera must be above
the object it is following. The code then simply smooths out that information
to make the camera follow our car. Now we need to select our camera node so we
can set our follow this path to point to our car. We must make sure that we set this to our
VehicleBody not to our container node. One last tiny thing I want to do before we
give this our first test run is to rotate the starting position of our car. When we run our demo so far we immediately
notice that our car has sunk into the ground. This is because with the default physics settings
our springs are not strong enough to hold the weight of the car and it is now resting
on our collision body. As you can see everything does work, we can
drive our car around just fine. This is mostly because our test environment
is just a flat plane. Our car would get stuck very quickly within
a real environment. For the last part of this video, let’s have
a look at the actual setting in the physics engine. We won’t get our car setup perfectly today
in part because of some of the small issues that need to be resolved. I will however try to do my best in explaining
what all the relevant settings should be. I will be showing these for one wheel only
and coping the settings to the other wheels. That is always a good starting point. For a real car setup you will often set the
rear wheels up slightly different from the front wheels. On the VehicleBody itself there is only one
settings that is relevant for us and that is the Weight. There are two settings here, weight and mass
but they are linked to each other. The weight is in kilograms and looking up
the specs for our Caterham I found a value of 575 kilograms which we will use here. One thing I realise now that I glossed over
in my video so far is the first two settings on our VehicleWheels that I had already set
up after importing the car. The first is use as traction which needs to
be on for our rear wheels as this is a rear wheel drive car. The second is use as steering which needs
to be on for our front wheels as we steer with those. The first setting to talk about is the setting
called roll influence. This setting is a bit of an odd duckling as
it is the only setting that is a bit of cheat. A car will always have a limited amount of
body roll as you corner, this setting is used to determine how much a car will roll. A low setting like this will result in very
little body roll. A high setting will likely result in a car
prone to flip over. We’ve already talked about radius so let’s
look at rest length. Now rest length is an important setting which
determines the distance between the centre of the wheel and the top of the spring when
the car is standing still. You can actually see the spring draw into
our interface and visually change when we alter this setting. There is one thing that is incorrect here
however and that is that the spring is drawn upwards while in reality our origin point
actually represents the mounting point of our spring and it is the tire that gets pushed
down. We’ll have to move our origin point upwards
to compensate for this. For our tiny caterham this rest length is
a little higher then it should be so we’re going to change it to 7 cm. Friction slip is a really cool setting that
determines the point at which a tire looses traction. The higher this number the less likely your
tire will loose traction. Use a very low number and it is like your
car is driving on ice. You can use fun tricks like setting the friction
of the rear tires lower then the front tires to create a car that easily oversteers. You can also simulate tire wear by slowly
decreasing this value for a tire that is getting worn out. The default setting of 10.5 gives us a very
grippy tire which is fine for now. Travel is another very important setting. While rest length determines the length of
our spring when the car is in rest, travel specifies the distance by which the spring
will compress or decompress. The total travel is thus twice this number. This value is again in meters so our default
value of 5 meters does not seem to make sense. I think this is just caused by some confusion
because the original value in bullet was indeed measured in cm and internally Godot converts
our value to cm. It should never be higher then the rest_length. In our case we’re making it equal. The stiffness setting determines how stiff
our spring is. I’m not sure what the units are but basically
the lower this number, the more bouncy the car gets, the higher, the more rigid the suspension
gets. A value of 5 is definitely too low and will
result in a car just bouncing around. You would use a value between 30 and 50 for
cars that need to go off road. A value between 50 and 100 would do good for
a race car while a value nearer to 200 is Formula 1 territory and will only work well
on very flat road surfaces. We will use a value of 70 for our car. The max force setting limits the amount of
force our suspension can absorb. If you put this value too low the spring will
not be able to hold the weight of the car and it will bottom out. If you put this value to a quarter of the
weight of that car the suspension will be just about strong enough to hold the car up
but the suspension will fail at the first bump in the road. A value of 6000 seems on the high side for
our caterham but I don’t see a reason to change it. The final two settings are the compression
and relaxation settings for our dampening. These are two halves of the same coin. If we didn’t dampen our spring the car would
forever bounce around. Just like real dampers on your car these damper
setting will slow the movement of the spring down. The default values of 0.88 are on the high
side and will stop the spring motion relatively quickly but for a race car setup they aren’t
too bad. You would normally set the compression slightly
lower then the relaxation. I’m changing them to 0.5 and 0.8 on our
caterham but they probably need to be tuned a little more. And with that we complete the first in this
series. As you can see the car drives pretty nicely. There is still loads to do and I’ll revisit
this in the near future. I will also place the demo on GitHub later
in the week. Thank you for watching. Please subscribe and hit that like button
if you enjoyed this.
Excellent - I would mention that even if you're not interested in vehicles specifically, this video has content related to texture/model sites, use of blender to prepare and export the model, bringing it into godot and setting materials, a nice little camera follow example, and more.
I love this video. I don't know anything about you, but I can tell you love cars because it just shows with the way you talk and explain things. Hearing people talk about things they love just makes me happy.
This is great, it's simple to understand but not too basic. Doesn't feel like just a tech demo, but really like one could turn this into a real game. Are you planning on doing more?
Pretty sure the imported recognized the wheels as such because you named them accordingly in Blender. Also the name of them is truncated on import, further adding to my hypothesis.
I've been searching for a 3.0 vehicle body tutorial for a week now. Thank you for creating this!
Badly needed, although it kinda highlights some of the problems with the physics engine.
I never liked the way Godot 3 swapped out the Bullet API for an emulated Godot 2 one. This kinda threw official Bullet resources to the wind.
One thing I wonder, with the collision box like this, won't the front/back of the car clip through any obstacles?