The very core of this game would be driving and handling of the vehicles. It needed to be as near to flawless as possible and extremely polished. This meant it would end up being the most time intensive part of development, and the most difficult to learn as a beginner coder.

Since I was building in Unity it meant they already have prefabricated wheelcolliders and even their own car demo as a resource. In order to fully understand what I would be making and to tune it to my specific needs, I skipped their vehicle demo and built my own with their wheelcolliders. Starting from zero coding experience, I had a rolling vehicle prototype working in a demo scene in just a few days. Like many others that experiment with wheelcolliders though, the vehicle slid, rolled over, struggled to change direction, and many other problems. I was immensely proud to already be driving in such a short time, but I had no idea how much more work it would take to get the vehicle handling the way I envisioned it.

I grew up in motorsport, or at least when I was younger. So I had a fair amount of knowledge about how real world vehicles handle and the various mechanics they employ to drive well. The physics in Unity aren’t inaccurate, a real vehicle with my first prototypes’ variables would have been just as likely to slide and flip. The very first thing I changed that made a massive difference, and a suggestion that is often tossed around in forums, was to use a realistically heavy mass for the vehicle to weigh down on the wheels. Unity wheelcolliders seem tuned to these realistic mass values at a minimum, with lower weights showing very glitchy behavior. One of the vehicles in my game is actually a smaller scale one seat modified car, but to handle properly in the game it’s weight is set far higher than it’s small scale would be in the real world. On average, vehicles in my game weigh 1400 kg, less or more depending on the vehicle type. It should be noted going much heavier than the average real car is fine with Unity wheelcolliders, something I did with my monster truck vehicle.

In my opinion, the suspension modeling of the wheelcolliders is fantastic. You can fine tune it to a variety of needs, but it can be extremely sensitive to the smallest variable change. For example, apply too high of a damper value and the wheels will bounce and rocket the car off the landscape. Too low and you’ll bounce on every landing. I’m making an offroad game centered around jumps and wild terrain so this had to be perfect. Each vehicle I made has different values for suspension stiffness and damper rates, which were fine tuned over hours and hours of testing.

Jumping lead to another problem though, most of my vehicles wanted to backflip on every jump. I planned on adding a degree of control to the tilt of the vehicle when in the air, but I didn’t want that tilt control to have to fight against the cars normal motion on every jump so heavily. (The tilt control will be covered in another blog post soon.) The solution to this, which also heavily improved handling and flip behavior, was to code in a custom center of gravity for each vehicle. A few simple lines of code and I could manually place the position of the center of gravity using an empty gameobject transform. Finding the perfect position for the center of gravity was another case of trial and error testing to get the right performance, more time put into each vehicles characteristics.

Now I have vehicles that drive, jump and land smoothly. Being offroad based, they also have quite a bit of suspension travel and the ability to soak up bumps while keeping momentum. But I haven’t even gotten to turning yet, which would be the hardest part of this whole process.

The cars tendency to rollover in turns was frankly ridiculous, even with the re-positioned center of gravity. Unity’s wheelcolliders have a variable that changes where the physics calculations on the wheel are carried out, sort of lowering the car without showing it. They list it as forced app point distance. While this could be effective, since this was an offroad game with trucks, big tires, and various obstacles I went with a more real world based approach. I decided to code in an anti-roll bar to add to each vehicles left/right pair of wheels. I experimented with a realistic approach where the wheels that are compressed on a turn transfer some of their compression to the opposite side to stop them from lifting the vehicle into a turn, effectively keeping the vehicle more flat. This helped, but not enough. I tweaked the code slightly so instead of just keeping the suspension geometry flat it would actually apply an opposing force to the roll as long as the vehicle is near enough the ground. The way I implemented this still allowed the truck to roll and lean with turns in a satisfying manner instead of remaining flat as if it had no real suspension. The force to keep the vehicle flat only really takes major effect when the wheels are at the extreme ends of their suspension distances.

Finally I can drive and turn without immediately crashing, but the cars had no hope of sticking to a trail or course. They slid around the terrain, in a fun way, but not what I was going for. I went to study the Unity vehicle demo to see how they locked it into it’s sticky turn behavior. Before implementing something someone else designed I wanted to have a full understanding of how it worked and how to implement it or modify it. In their demo they use a helper piece of code that normalizes the vehicles forward direction with the direction of travel. In their vehicle, they have this tied to a value that makes the car handle as if it’s wheels were magnets on a metal track. Way too powerful for my needs. I coded it into my car controller and found different values of it’s strength to apply to my vehicles, a subtle effect that let them handle much more predictably. Now I could paint trails on my terrain and hope to actually drive on them, while I still had a satisfying amount of drift and slide behavior for the dirt and snow terrains I would be making.

Now that I could finally get real time testing the driving it was time to fine tune the tire friction variables of the vehicles. Up until now they were merely satisfactory, but I wanted each vehicle to handle slightly differently, predictably based on the type of vehicle itself. With each vehicle having unique weight, suspension geometry, and center of gravity, this meant hours more testing and refining and testing again. Finding the perfect balance for each variable, which Unity’s wheelcolliders have many for tire friction, was an intense experience. In the end it was very worth it, further refining that balance of grip and dirt-surface like slide.

This had taken months to get to this point, and while it finally felt like a real vehicle in the game, it still wasn’t enough for me to be happy with it. As a mobile game, the input would be very limited. For the time being, I have no tilt steering input. Instead buttons on the HUD send full turn values for left or right. Initially this meant a left button press made the wheels instantly turn to full lock position, different degrees of lock per vehicle. This worked okay, but at high speed could be a real problem. I spent some time studying racing and driving games and coupled with real driving know how I settled on coding in some steering behavior to help the handling at all speeds. First I added a time delay to the steering movement, so when pressing the turn button the wheels would take x amount of time to move into full lock position. Then came the first of many speed based variables that would go into my car controller code. I set it up that as the vehicle speed increased, the time it took to turn the wheels into their full turn position would take longer, and shorter with decreased speed. At top speed, around 138 mph in my vehicles, the degree of turn on the wheels was more than it should be, but appropriate for slow speeds. I added in a function to change the degrees of full locked steering to the vehicle speed as well so that as car speed went up, the degrees the tires would turn went down. Each vehicle in my game has custom values for slow speed steering degrees, high speed steering degrees, the speed that high speed steering ratio is in effect, and the time it takes to turn the wheels into position at differing speeds. Lots of lerping values and variables for a small, but in my opinion very necessary addition to the feel of driving in the game.

It’s almost a real driving game now. Except when I need to stop. Up to a point the only braking the vehicles had was reverse torque when the player pressed the reverse/stop button. The cars would skid for near a mile if stopping at top speed, totally useless. I added an if check to the code that checks for forward direction above a certain speed and placed some code to use the wheelcolliders brake torque to slow the vehicle more naturally. If the torque was too high though the vehicle would immediately start doing frontflips and lose total control. The solution was to balance the brake torque value between the front and rear set of tires as well as increased general drag on the vehicles rigidbody while grounded and braking. The combination of these two works tremendously well, especially to regain control of the vehicle in desperate situations.

All this while I haven’t discussed the motors in these vehicles. I could have spent ages coding in a transmission and gear ratios, and I may at some point. But for now I just use the motor torque on the wheelcolliders with variables that don’t change. In order to balance the race mechanics of the game I placed a top speed limit on each vehicle. The torque values I used for satisfying acceleration hit that limit too quickly though, so I added a changing drag variable that increases with vehicle speed. The feel of this is very natural, as the rate of acceleration slows down the faster the player drives. Along these same lines, I placed a downforce function into the car controller so that the mass slightly increases with speed. A small effect, but still a noticeable polish to the handling characteristics of the cars.

In the end I finally got the performance out of the vehicles and handling that I wanted, after endless hours of testing and learning. In short the basis of it is physics handling in code and loads of dynamic variables based on what is happening to the vehicle at any given moment. Most of these functions I coded in are based on real world study and experience with cars, such as the dynamic steering ratio and anti-roll bar. Finally I’m enjoying driving, but this is not a complete game yet. More to come soon.

Share this: Twitter

Facebook

Like this: Like Loading...