Dana Vrajitoru
I355/C490/C590 3D Games Programming

I355/C490/C590 Lab 1 B

Date: Wednesday, September 2, 2026. To be turned in by Wednesday, September 9, 2026.

In this lab, we will continue the work started in Lab 1 A and turn the project into a game of Racquetball.

To keep it separate from Lab 1 A, from the Unity Hub, create a new project called Racquetball.

Assets - Scene

In the Project area in the bottom left quadrant, note a folder called Assets and a subfolder called Scenes. The Assets folder is where we normally store all the resources needed for the project. If there is no folder inside called Scenes, just create one using the + button below Project. The current scene should be in this folder under the name SampleScene. Rename it in the folder as Game and then click the button to reload it with this new name in the dialog that the editor opens. Save your game (the scene) from time to time.

In the Assets folder, create a folder called Materials and one called Scripts.

Copying a Scene

To copy the content of the scene from the previous project, we will copy the whole scene from it. Open the previous project in Unity, then right-click on the Scenes folder and select Show in Explorer. Do the same thing with the new project. Then in explorer, open both Scenes folders, and from the first one, copy both files MainScene.unity and MainScene.unity.meta, and paste them in the second one.

Go back to the new project in Unity and double-click on the MainScene scene to open it. Rename it as Game and then click the button to reload it with this new name if a dialog opens asking to confirm. Save your game (the scene) from time to time.

Ground

First, let's create a plane for the box to sit on. Click on the + button below Hierarchy and on 3D Object - Plane. Note an object appearing as child of the scene Game. Using the Inspector on the right side of the window, rename this object as Ground.

Also in the Inspector, change the scale of this object to 3 x 3 x 3 to make it large enough to have space to hold the box on it. Change its position to (0, 0, 4.5). Note that the horizontal plane sits on the X and Z axes and that the vertical is the Y axis. The box should be centered on it horizontally.

You can take a moment to get used to the navigation in the scene editor:

Now, let's make this object green. At the bottom of the inspector, notice a material component that looks like a white sphere. We'll replace it with another material. In the Assets folder, click on the Materials folder on the left. Then using the + button below Project, create a new Material and give it the name green. With this material selected, notice the property Base Color in the Inspector. Click on the big white rectangle and change its color to a medium green. Now, all we need to do is to drag this material from the assets and drop it over the plane in the scene editor to apply it to this object. When you click on the Ground object, it should show the Green material in Material component in the Inspector.

Box and Ball

Back in Windows Explorer, you can also copy the bounce physics material and the red material from the old project to the Materials folder of the new project. Make sure to copy both the file itself and the associated .meta file to avoid problems. Copy the script file from the previous project and paste it in the Scripts folder in the Assets. If you click on the ball after that, they may automatically be recognized. If not, you can apply them to the object again.

We'll remove the front wall because we want the ball to be caught by a paddle on that side. For this, click on the Z arrow in the navigation gizmo, select the wall in the front, then un-check the mark next to its name in the Inspector to disable it.

From the + button below the Hierarchy, create an empty object and call it Room. Select all 6 walls and move them over the Room object to make them children of this object. Then change the scale of the Room object to (2, 2, 2) and the position to (0, 0, -4.5). You can apply whatever material you want to them.

Change the scale component of each wall that is equal to 1 to 0.5. Manually adjust the positions of the walls so that the box looks whole.

Set the ball's position to (0, 10, 5) to place it in the center of the box. Change its scale to (1.5, 1.5, 1.5).

Change the position of the Main Camera object to (0, 10, 33) and the rotation to (0, 180, 0). You can play with adjusting the camera angle and proximity to the scene (Z coordinate) to see if you can get a setting that looks better.

Calibration

Next, we would like to be able to calibrate the ball's speed without recompiling the code. Let's add an attribute speed in the code at the top of the class:

public float speed;

Then replace 10f everywhere in the velocity by this variable. Save the file and go back to Unity. In the Inspector, under the script component, we should have an extra attribute Speed. Set its value with something like 20, then run the program to see if it works.

In the function Start, change the x and y ranges for the initial speed to (-speed, speed) but keep the one for z between (0f, speed). This way, the ball will initially move away from the player when it starts out.

Racquet

Let's create an object that will play the role of the racquet, so that the user can interact with the game. Add a new object to the scene of type Cylinder. Set the scale for this object to 2 x 0.05 x 2, and then the rotation around x to 90 degrees. Set a material for the racquet where the Alpha component of the Base Color is somewhere in the middle. Then switch the Surface Type from Opaque to Transparent. That way, we'll be able to see the ball through the racquet. Switch to a side view and move the paddle to the inside of the box using the green arrow, a little bit ahead of the camera. Rename the object Racquet.

Now, we need to be able to move the racket around to try and catch the ball. For that, we also need to add a script to it. Add a new script component to the racket and call it RacquetControl. Add a public attribute speed, also of type float. Then add the following attribute to the class:

public KeyCode moveUp, moveDown, moveLeft, moveRight;

Declare a private attribute of type Rigidbody called rb. In the function Start, get a reference to the rigid body component of the object and store it in the attribute rb:

rb = GetComponent<Rigidbody>();

We need to add a setting to be able to use the Input class, as it is deprecated. In later homework assignments, we will switch to the new system. For now, from the Edit menu select Project Settings. Click on Player on the left, scroll down to and expand Other Settings, then inside it, scroll down to Configuration. Next to Active Input Handling, switch the option from Input System Package (New) to Both. 

Then in the function Update, add the following code to move the paddle when the up arrow key is pressed:

if (Input.GetKey(moveUp))
    rb.linearVelocity = new Vector3(0f, speed, 0f);

Add 3 more similar cases for the other directions of movement, each of them on an else from the previous if. Add an else to the condition where you set the velocity to 0.

Going back to Unity, first add a Rigidbody component to the racket and un-check the Using Gravity setting. You should see 5 attributes added to the script component in the inspector. Set the move attributes with the arrow keys or the WASD keys. Then set the speed to 1. Try the game and adjust the speed if needed. You can now make the front wall visible again so that the ball doesn't get lost passing through it.

In the rigid body component, expand Constraints, and the check the boxes to freeze the rotation in all directions. Otherwise when the ball collides with the racket, it could give it a spin. The same way, freeze its position over Z. Then also change its collision detection from discrete to continuous.

Collision. In the last part of the lab, we will handle the collision between the racket and the ball. We would like to have a score in the game and to have it increase every time there is a collision between the ball and the racket.

We will make the ball in charge of keeping the score and detecting the collision with the racquet. But first, we need to add a tag to the racquet that will identify it as such, so that the ball can tell it apart from the walls.

Select the racquet, then in the Inspector, just below the name of the object, click on the menu next to Tag and click onAdd Tag. Click on the + to add a new user tag and call it racquet. Then select the racquet object again and change its tag to this one.

In the ball controller script, add a public integer score initialized as 0. Then add the following function to the same script. Do not call it explicitly because the engine will call it automatically when a collision happens:

void OnCollisionEnter(Collision colInfo)
{
    if (colInfo.collider.tag == "racquet")
    {
        score += 1;
        Debug.Log("Score: " + score);
    }
}

Test the program to see if it works. Click on the Console next to the project browser on the bottom left to see the score displayed. This will be continued in the homework.