Monday, September 12, 2022

Driving Game - introduction to visual scripting


Welcome to the Unity. In this project, your are going to make vehicle driving game by using real physics simulation, just like it's done in games done by professional studios! Open provided starter project and take a look around, you should see the car is already there, waiting for code to make it go!

Quick introduction to unity interface


The window in the middle shows our game scene. On the left side, we have the Hierarchy panel, which lists all objects in our scene. On the right side, the Inspector panel shows various components and properties of currently selected object. And finally, on the top of the screen, we have very important Play button, that will allow us to start and stop our game. Don't worry if it looks a bit overwhelming at first, you will soon figure out what everything does!

Make the car move

As you can see, our car is very basic, it has a body and three wheels. Let's make it move. First, select the “rear right wheel” in the Hierarchy panel on the left (you might need to "open" the car by clicking gray triangle next to it) and then click on the Edit Graph button on the Inspector panel to the right. This will open our script. Alternatively, you can just click the wheel in the scene view.

Now this is where programming begins. It’s a bit similar to scratch, where you connect various blocks together. On Update Event will fire every frame (many times per second, just like forever loop in scratch). While the Wheel Collider Set Motor Torque is going to make the wheels rotate, and in turn, propel our car! 

Before continuing, click the “Play” button on top of the screen, that way we will be able to see what is happening to our car while we are coding. 

Let’s make our car move. Connect On Update Event to Wheel Collider Set Motor Torque, and set the value of the latter to 500, so it’s going to add plenty of torque (torque is just a force, but rotational one). Now watch the car go, and promptly crash into the orange cube... Congratulations, your first unity program is working!

Feel free to experiment with different values. What happens if you set the value to -500? Or 5000? If at any time your car becomes unusable, just restart the scene by clicking the "Play" button to turn off the play mode and then click it again to restart it. 

Control acceleration with keyboard or game controller



Controlling the car by typing value into the script is not the most convenient way, lets make it better. Note the other two nodes in the graph, one of them is Get Input Axis. This one will output a value between -1 and 1, depending on how far we move gamepad/joystick, or, if we don't have a game controller, which keys we are pressing on the keyboard. The up and down arrow keys control the "Vertical" axis, while the left and right arrow keys control the "Horizontal" axis. But since -1 and 1 is not enough to move our car, we need to multiply it with the Multiply node, before finally setting it as our torque. 

Connect the nodes together as shown, make sure to put 500 as the B argument of the Multiply node, and now you can control acceleration of the car with up and down arrow keys. Congratulations, you are half way to having a working car!

Note how values change on the graph while you are pressing the up and down arrow keys. It will come in handy whenever we try to understand what is happening in our code. 

Make our car turn

Let's switch to the "front wheel" now by clicking on it in the Hierarchy panel. The Script Graph window should automatically switch to its script, but if you closed that window, just click again on Edit Graph in the Inspector panel.

Does it look similar to the previous script? The main difference is that now we will be setting steering angle of the wheel. If you click on the Wheel Collider Set Steer Angle node, The Script Graph window will display its description, which can be very handy!

Can you connect the nodes and setup the value in order to let the player steer the wheel with left and right arrow keys? Feel free to take a peek at the image below if you need a hint.



Congratulations, you can now drive the car around!

Lets add a proper goal to our game. While we do have a finish line, it does not show us how fast we got there. Let's fix that!

Counting the time to reach the finish line



Click on the "Finish Line" to open its script. It's slightly more complicated, but don't worry, it's pretty straightforward.

The Timer node is very convenient node that makes counting the time very easy. It not only keeps track of the time for us, it also fires its Tick output every frame for as long as its active, working a bit like loops in scratch. Additionally, the Elapsed output will give us the value of how long the timer is active so far (in seconds).

First, let's start it by connecting it to the Start Event. Since the event only fires at the start of the game, you need to restart your game for that to work. Then, connect the Tick output to the Set Text node, which will set the displayed text to the value we provide. But how do we get the value?

Elapsed to the rescue, connect it to the To String node, which will change it into neat text value. And finally, connect the output of the To String node to the value input of the Set Text node.




And don't forget to pause the timer once we cross the finish line by using the On Trigger Enter Event node.

Phew, that was some fancy coding. But now you have created real working game, congratulations! Can you beat my 12.5s time from the image?

Additional challenges

Improving the car

As you probably noticed, our car does not look very good, and is very unstable... Can you make it better? Add wheels? Nicer Shape? More windows? Feel free to experiment!

Improving the track with Pro Builder

How about making the track more fun and challenging! Play around with Pro Builder panel, add as many obstacles as you want. Can you make the track so challenging that only you will be able to finish it?

 


 

Pro Tip: Shapes that you add with Pro Builder are static by default, which means they won't move, no matter how hard you crash into them. But if you add Rigidbody component to them (use Add Component button in the Hierarhy panel), they will react according to the law of physics. Experiment by changing their mass, and see how differently they behave!

Adding sound to the car 

This one involves little bit of math, but since computer will be doing most of the work, no big deal. It's all about calculating our velocity, and then modifying pitch of the sound (how fast the sound is playing) depending on calculated velocity. Scary looking Inverse Transform Vector node is there to turn our velocity from world space to car space, so we can get our forward velocity easily. Then we divide it by 5 (feel free to experiment with the value), set it as pitch of our sound and done, our car sounds "faster" the faster it goes!



Make it two player game

This one is going to be fun. Challenge your friends and see who can win!

If we duplicate our car, we do get fully working second one, but one player controls both! How do we tell the care to be controlled by different set of keys? Variables to the rescue!

Note that for Input Get Axis, we can define which axis it reads. Luckily, we have more axes defined in our project, like Horizontal2 and Vertical2, which are controlled by WSAD keys (you can check them all by going to menu Edit->Project Settings->Input). Let's create object variable of type string and read the name of our axis from there. Create it for each wheel, and set it so first car will use Horizontal and Vertical, while second car will use Horizontal2 and Vertical2. Then, modify drive and steer scripts so they read our variable.

Success, each car now can be controlled independently!