Menu

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

January 12, 2015 - Pong Tutorial

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:

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.

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.

 

 

Tags: ,

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

  • Pingback: Beginner’s Guide: Create a Pong Clone in Unity: Part 4 « Unity for All Unity for All

  • Pingback: Beginner’s Guide: Create a Pong Clone in Unity: Part 4 | Unity for All

  • Tam

    I cannot find the player 2 check box in the inspector

    Reply
      Damien

      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.

      Reply
    Tam

    i am still getting compiler errors even though i copy and pasted your code

    Reply
      Damien

      What errors? That code has been tested and works fine. Is your script’s file the same as the class name (PaddleScript.cs / PaddleScript)?

      Reply
    Tam

    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.

    Reply
    Dan

    My paddels go though the walls, help?

    Reply
      Damien

      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
      }

      Reply
        Dan

        Wow thank you for the quick response! Very helpful 🙂

        Reply
    Avi

    My Paddle is going through the wall and I don’t know what to do. Could please help me

    Reply
      Damien

      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.

      Reply
    Avi

    My paddle stops at the middle of the screen and goes down through the screen Please help and can you tell me where the code goes.

    Reply
    Oz

    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?

    Reply
      Damien

      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.

      Reply
    Ronald Bahre

    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.

    Reply

    Leave a Reply

    Your email address will not be published.