Beginner’s Guide: Create a Pong Clone in Unity: Part 5

Moving the Paddles

Now that we have a moving ball we need to also move the paddles so we can hit it, and once that is done we have the skeleton of a working game!

We’ll be moving the paddles via a script, and we are also going to be getting player input to move the paddles.

Pong Controls

Our Pong will be a 2-player game, with the following controls:

Player 1

Q – Up

A – Down

Player 2

O – Up

L – Down

Create the Paddle Script

Create a new script (remember to put it in the Scripts folder to keep the project nice and neat) called PaddleScript.

I’ll give you the full script code and then explain what it is doing. Open PaddleScript in MonoDevelop and replace its contents with the following:

using UnityEngine;
using System.Collections;

public class PaddleScript : MonoBehaviour {
 [SerializeField]
 bool isPlayerTwo;
 [SerializeField]
 float speed = 0.2f; // how far the paddle moves per frame
 Transform myTransform; // reference to the object's transform
 
 // Use this for initialization
 void Start () {
   myTransform = transform;
 }
 
 // FixedUpdate is called once per physics tick/frame
 void FixedUpdate () {
   // first decide if this is player 1 or player 2 so we know what keys to listen for
   if (isPlayerTwo)
   {
      if (Input.GetKey ("o"))
         MoveUp ();
      else if (Input.GetKey ("l"))
         MoveDown ();
   }
   else // if not player 2 it must be player 1
   {
      if (Input.GetKey ("q"))
         MoveUp ();
      else if (Input.GetKey ("a"))
         MoveDown ();
      }
   }
  
   // move the player's paddle up by an amount determined by 'speed'
   void MoveUp()
   {
   myTransform.position = new Vector2(myTransform.position.x,   myTransform.position.y + speed);
   }
 
  // move the player's paddle down by an amount determined by 'speed'
  void MoveDown()
  {
     myTransform.position = new Vector2 (myTransform.position.x, myTransform.position.y - speed);
  }
}

Explaining the Script

Firstly, we have a few variables:

  • bool (true/false) isPlayerTwo –  to specify which copy of the script is for which player.
  • speed – how quickly the paddles move, which can be changed in the Inspector to make the paddles faster or slower.
  • Transform myTransform, which we will use to hold a reference to the GameObject’s transform component.

In the Start() method (which runs as soon as the scene starts), we set myTransfrom = transform. This stores a reference to the current GameObject’s transform in the myTransform variable.

We store references to components because it is more efficient than making Unity ‘find’ the components every time they are needed.

We then use the method FixedUpdate(), which is a MonoBehaviour method similar to the Update() method we learned about in Part 4. The difference between the two is that FixedUpdate() is fixed to the physics engine clock, meaning it runs with the same frequency regardless of the device and/or framerate, whereas Update() will run as often as the available computing power will allow. FixedUpdate() is consistent, and all physics calculations should be done there.

In FixedUpdate() we check which player this script instance is assigned to by checking isPlayerTwo. It then checks if the player’s up or down key is being pressed by using Input.GetKey. If one of the keys is pressed, either MoveUp() or MoveDown() is called (see below).

Move Methods

Two simple methods move the player’s paddle up or down by changing its transform.position.y value.

You can’t simply change the transform.position.y value. Instead we create a new Vector2 (a point in 2D space – sort of) with the current X value (we don’t want the paddle to move left-right) and the current Y value plus or minus our speed variable (plus for up, minus for down).

Attach the Script

Now you must attach the script to the players.

  • Select PaddlePrefab in the Assets/Prefabs folder.
  • Drag PaddleScript script into the Inspector.
  • Note: Now that the script is in the prefab, it is also in the Player1 and Player2 objects (since they are instances of the prefab).
  • Select Player2 in Hierarchy.
  • Tick the Is Player Two check box in Inspector. This lets the script know which keys should control the paddle.

Test the game in play mode, and it’s now a functioning Pong clone…in a minimal sense. You’ll probably notice the ball moves too slowly, and there is no scoring, and minimal control for the players. We’ll work on those things in the rest of this series.

Recap

We added a new script to our paddles, including some new functionality to detect key presses. We learned how to move a transform by changing its position using a new Vector2.

If the scripting is still a bit mysterious to you, have a read through the code, and even try changing a few values to see what happens (you can always re-copy the code above if you break your script).

When you’re ready, continue to Part 6.

16 thoughts on “Beginner’s Guide: Create a Pong Clone in Unity: Part 5

    • Make sure the [SerializeField] is there, as that is what causes the variable to show in the inspector. Note that the script needs to be saved and compiled by Unity before the inspector is updated. If there are errors this can’t happen.

  1. I do apologise my mistake, i have now fixed the issue. Thank you for this tutorial it has helped more than any other i have found.

    • The code does not take the walls into account when moving the paddles, so this is the expected behaviour.

      To stop the paddles going through the walls, you should set minimum and maximum ‘y’ positions for the paddles. You could easily hard-code these values by creating two variables: ‘minPaddleY & maxPaddleY’ for example, and then move one of the paddles to the highest position (touching the wall), then take the y value and give that to the appropriate variable.

      Then, when you move the paddle, you will need to ‘clamp’ the position, so if the new y position is going to be higher than the max, override it to be the max. Something like:


      void MoveUp()
      {
      Vector2 newPosition = new Vector2(myTransform.position.x, myTransform.position.y + speed); // calculate the new position based on movement
      if(newPosition.y > maxPaddleY) newPosition.y = maxPaddleY; // if new Y pos moves paddle past the max (i.e. into the top wall), force the Y position to the max (i.e. just touching the wall)
      myTransform.position = newPosition; // move the paddle
      }

    • Avi,

      Look in these comments, as I have previously posted a reply to the same question. The tutorial itself doesn’t try to stop the paddles going through the walls, but you can use the code I posted earlier in these comments to add that behvaiour.

  2. I have a problem with the script, if IsPlayerTwo is not checked I move both paddles at the same time with q/a, if it’s checked I move them with o/l. How can I move the paddles separately?

    • The only two things I can imagine that would cause this behaviour are:

      1) You have set the isPlayerTwo variable to be static(i.e. static bool isPlayerTwo), or
      2) There is something wrong in the FixedUpdate code.

      Most likely #2. Double check that the code is exactly as in the blog post. Copy and paste it. You might have the braces in the wrong places, which would break the logic of checking if it’s player two before determining which keys to listen for.

  3. The ball goes through the paddle and only bounces off the first wall it hits. After that it goes through the wall. If the ball goes through the paddle it will not bounce off the wall behind it. What did I not set on the prefab.

Leave a Reply to Oz Cancel reply