Creating a 3D Smash Game in Unity – Part 2

Introduction

Benjamin Franklin once said, “the best video games that I have ever made were the ones where I persisted and didn’t give up.”* Whether or not Benjamin Franklin actually said this, he is right. Welcome to Part 2, and congratulations on continuing this tutorial series on creating a 3D Smash Game in Unity! In this tutorial, we will be tying everything together into a complete game. We will be using the Scriptable Render Pipeline to add a shader to our glass and our ball. And we will set up a UI system for the start and end of the game. With that runthrough, let’s get started!

Check out Part 1 if you haven’t already

This tutorial is part of a series. You can check out Part 1 here. This is where you’ll also get the link to the Source Code files, as you won’t need to download additional ones from this part onwards.

Did you come across any errors in this tutorial? Please let us know by completing this form and we’ll look into it!

FREE COURSES
Python Blog Image

FINAL DAYS: Unlock coding courses in Unity, Godot, Unreal, Python and more.

Creating the shaders: Glass

Before we get started using the incredibly awesome SRP (Scriptable Render Pipeline), we need to first import the package. Go to Window -> Packages,

Capture

… and download (or update) the Lightweight Render Pipeline.

Capture1

Once it is finished importing, go to your Materials folder and right-click. Go to Create -> Shader -> PBR Graph.

Capture2

Call it “GlassShader” and then double-click on it to edit it.

Capture3

You can dock this window where ever you like, I either keep it in the editor window or detached completely.

Let’s talk glass, how do we go about making a glass shader? This is probably oversimplified, but for our intents and purposes, glass has a transparent component and a reflective component. There are other things like scratches and smudges which give a different set of looks but for all we need to know, glass is reflective and transparent. With this in mind, we could go for a hyper-realistic type of glass, or we could make it sort of stylized. Since we don’t have access to vast amounts of textures to make it look hyper-realistic, we will be going the “stylized” glass look. But how do we create a reflective and transparent glass? It is really simple, go to your “GlassShader” window and change the shader type to be transparent:

Capture4

This just means that we can apply values to the Alpha field. Right-click and select “Create Node”.

Capture5

Search “Fresnel” (pronounced Frah-Nell),

Capture6

create a “Fresnel Effect” node and drag the output into the “Alpha” socket on the material node.

Capture7

What does a Fresnel node do? In our case, it makes the edges opaque and the centre transparent, which is perfect since we are making a glass material.  The trick here is to find the right value for the power socket on the Fresnel node. What I did was to actually create a Vector1 property called “Fresnel Power” so that I can change this value in the editor without having to access the shader.

Capture8

If you’d like, set a color for your glass

Capture9

(I did a light blue) and then hit “Save Asset”.

Capture10

Create a new material called “GlassMat” and set the Shader to be our “GlassShader”.

Capture11

Now it’s just a matter of tweaking the “Fresnel Power”  in order to get the look your after. You could make it harder for your players by making the glass more transparent, or you could be merciful and make it slightly more opaque, it all up to you (I would try and be merciful).

Capture12

When you think you’ve found the right value, we need to assign it to our glass objects. This, I found, was slightly tricky. We want the glass shards to have the same material as the glass pane. The best way to do this is to drag each broken glass prefab into the hierarchy:

Capture13

Group select a few shards and then drag the material onto the selected objects.

Capture14

Keep doing this until all of the glass (whether broken or whole) has the Glass Material. It can be tedious so just get through it as fast as possible. Once you are done, apply your changes to the prefab.

Capture15

Creating the shaders: Steel Ball

If you thought the glass shader was simple, wait ’till you see the shader for the Steel Ball! Go to the Materials folder and create a new PBR Graph called “BallShader”.

Capture16

Double-click on it and let us start making this shader! Change the workflow type on the base node to “Metallic”. That’s it! Now it’s just a matter of changing the “Metallic” value to make it look like a shiny steel ball. If you’d like, you could also make this a float property called “Metalness” (or something else that doesn’t sound as ridiculous) and then you could change its value in the editor. You might fiddle around with the Smoothness and Occlusion values if your ball still isn’t the way you’d want it to look.

Capture17

Once, you’ve finished tweaking those values, that’s it for our Steel Ball shader! Create a new material called “BallMat” and assign our “BallShader” to this new material. Then we drag this material onto our ball prefab to see how it looks!

Capture18

If it looks good, apply this change to the prefab.

Creating a level: Ground

Now that we have our shaders setup, let’s create a level to place these things in. First, I am going to create a plane so that our shards fall and bounce around, making it look much more realistic. When creating a level, I actually got creative and made several different planes, each with different sizes. I encourage you not just create one flat plane for your entire level, create several. Spread them apart and angle them if you think it looks cool. Just get creative! Second, I assigned a material to the plane to make it look less like a 3D primitive and more like an actual part of the game. The material I used was in ExampleAssets -> Materials. Just pick one that you think would go well with your scene. Here is my final result:

Capture19

Feel free to make your level longer or shorter.

Creating a level: Glass Panes

Now that we have a ground, let’s add something on top of it. We are now going to be adding the glass blocks to our scene. When you do this, I have one command that you MUST follow, BE CREATIVE! Seriously, just go crazy! I have found it is best to place the glass blocks slightly above the ground so that the glass shards have room to fall, but, if you place the glass so that it is slightly overlapping the grounds, the glass will explode if you hit it. With this in mind, start creating! Here is my finished level:

Capture20

Adding a UI Canvas: Restart Button

If you notice on your CameraCharater script, there is a field called “Button”.

Capture21

If you look at the code:

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("glass"))
        {
            collision = true;
            Debug.Log("Collided with glass!! Man down!!");
            camMoving = false;
            button.SetActive(true);
        }
    }

You’ll see that this button is activated when the camera collides with the glass. If you were scratching your head when you put this in your code I am now going to explain why it is there. In the original game (do not go and download it! You are making your own now so you don’t need the original), there is really only one scene. This means that the UI controls whether or not the game is running or stopped. Because of this, we use a button to restart the scene so that the player isn’t jarred back to the beginning immediately. Go to the hierarchy and create a new button called “Restart”.

Capture22

In the CameraCharacter script you’ll notice a public method called “Reset”:

public void Reset()
    {
        SceneManager.LoadScene("Scene1");
    }

This is the method that will be called when we press our Restart button. Change the text on the button to say “Restart”,

Capture23

Create a new “OnClick” action, drag the Camera into the field, and set the called method to “Reset”.

Capture24

Disable the button, assign it to the proper field on the Camera:
Capture25

…and hit play. Now we have a button that resets the game when we collide with a piece of glass!

Capture26

There is just one thing I think we need to do before we are finished with the UI Canvas…..

Adding a UI Canvas: Start Button

…and that is to add a start button! It may seem like a trivial thing but it gives more control to the player which, in the case of our game, is a good thing. Create a new button called “Start” and place it directly over our Restart button.

Capture27

If you have another look at the CameraCharacter script:

public void StartCam() {
        camMoving = !camMoving;
    }

You’ll see that there is a public method which sets a static boolean to a value different to what it was originally (by using the !boolean syntax). This boolean is false by default:

    public static bool camMoving = false;

You’ll also see that the Update method has a series of logic statements which use this variable as well:

 //This checks if we have collided
        if (!collision && camMoving)
        {
            cameraChar.Move(Vector3.forward * Time.deltaTime * speed);
            //This is so that the camera's movement will speed up
            speed = speed + incrementFactor;
        }
        else if (collision || !camMoving)
        {
            cameraChar.Move(Vector3.zero);
        }

        if (Input.GetMouseButtonDown(0) && camMoving)
        {
            GameObject ballRigid;
            ballRigid = Instantiate(ball, BallInstantiatePoint, transform.rotation) as GameObject;
            ballRigid.GetComponent<Rigidbody>().AddForce(Vector3.forward * ballForce);
        }

From a quick glance at where this variable appears, do you understand how it we are using it? We have a boolean that is static (in case we have other scripts that want to stop or start the camera) which dictates whether or not the camera is moving or not. So when we start creating this Start button, all we need to do is call the method which sets a different value to this boolean. And you know which method that is!

public void StartCam() {
        camMoving = !camMoving;
    }

Go to the Start button and create a new OnClick event. Assign the camera to the field and set the called method to be “StartCam”. Don’t forget to also change the text to read “Start”.

Capture28

Now hit play and let’s see what it looks like!

Capture29

It works, but the buttons are cluttering up our game view. They stay active even after we have pressed them. Let’s just have the Start and Reset buttons disable themselves whenever they are pressed. Create a new OnClick event in each button, drag the instance of each button into their respective OnClick event, then set the action field to “Gameobject -> SetActive”.

Capture30

Leave the box unchecked on each one and we now should have a clean game view.

Capture31

Well, I think that is all we need to do for the UI! Obviously, as it is, the buttons are very ugly so please make them more interesting. Here is another opportunity to get creative!

Fixing the Sky

Our game is almost complete! There is just one thing that I find not as aesthetically pleasing and that is the sky.

Capture32

Now it may not bother you at all, in which case, just leave it as it is. But, I feel it would add another level of ambience if the game had a different color or style of background. In this case, I found it was only necessary to change the default skybox which can be found in the Materials folder.

Capture33

This is a good thing to remember since you can get lots of varied looks without having to create your own skybox. I decided to have a go at tweaking these values.

Capture34

I wanted a darker background because this would create a nice contrast between the dark sky and our light colored glass panes. In the end, I decided that these values were the result I was looking for.

Capture28.5

In order for this to work though, we need to bring add a Skybox component to the camera and place the finished skybox in the “Custom Skybox” field.

Capture35

Let’s hit play again and just appreciate our game for all its fine aesthetics and mechanics.

Capture36

Conclusion

Congratulations on finishing this tutorial, you can check out part 3 next! At this point, you have learned 2 things, how to make a game similar to a popular mobile game, and what to do if you have no idea what kind of video games to make. It’s no small feat to have made this much progress. I hope you have enjoyed this tutorial series so far and found it useful. I’ve got nothing else to say except:

Keep making great games!

*Editor’s Note: Sadly as of this moment the historians haven’t discovered any evidence yet that game design was part of his famed routine.