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 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.
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.
I cannot find the player 2 check box in the inspector
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.
i am still getting compiler errors even though i copy and pasted your code
What errors? That code has been tested and works fine. Is your script’s file the same as the class name (PaddleScript.cs / PaddleScript)?
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.
My paddels go though the walls, help?
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
}
Wow thank you for the quick response! Very helpful 🙂
My Paddle is going through the wall and I don’t know what to do. Could please help me
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.
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.
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.
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.