Now that we’ve got some experience scripting, we can get slightly more advanced with the creation of our Paddle. In this lesson we will create the bar which moves back and forth across the screen based on user input.
Continue following along with your existing “Breakout” project. Otherwise, you can start from this sample project here.
Create The Paddle
Create a new static rigid body (like our walls) named “Paddle”. Set the Transform “Position” to X: 0, Y: -4.5, Z: 0 and to “Scale” of X: 1, Y: 0.2, Z: 1.
Change the Rigidbody 2D “Body Type” to “Kinematic”.
Create The Script
Create a new C# Script named “Paddle”, and open the script for editing. Replace the contents of the script with the following code, and then save your script.
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Paddle : MonoBehaviour { [SerializeField] float maxOffset = 1.5f; Rigidbody2D rb; void Start() { rb = GetComponent<Rigidbody2D>(); } void Update() { var target = Camera.main.ScreenToWorldPoint(Input.mousePosition); var position = rb.position; position.x = Mathf.Clamp(target.x, -maxOffset, maxOffset); rb.MovePosition(position); } }
About The Script
Take a look at the script and see how much about it you can understand based on the overview in the previous lesson.
[SerializeField] float maxOffset = 1.5f;
We start by adding a field named “maxOffset”. This has a data type of float, and a default value of 1.5, which is the number of units we can move the paddle before it hits the wall. Even though the Paddle will take part in the physics system collisions, in the sense that it can move other bodies, its own position is controlled manually.
Rigidbody2D rb;
We add a second field named “rb” which will hold a reference to a rigidbody. It is not provided a default value.
void Start() { rb = GetComponent<Rigidbody2D>(); }
We use the Start method once again to grab a reference to the rigidbody. It is slightly different though, because we are assigning it to a field in our class instead of to a local variable. The reason we are doing this is because we will need to use this reference repeatedly, and storing the reference helps optimize the speed of our running code.
void Update() { // ... }
The “Update” method is another special method provided by MonoBehaviour. This method will be called repeatedly, prior to rendering each frame of our game.
var target = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Inside the Update method, we use a special method on Camera, that accepts a parameter. The parameter we provide is the position of the mouse. The method then converts the coordinate from its “pixel” location, to the equivalent world “unit” so that we know where it is relative to the game objects in our scene. That position is the “return” value of the method, which we store in a local variable named “target”.
var position = rb.position;
Next we make another local variable named “position” which is a copy of the position of our rigidbody. This is because we will be changing the “x” position, but keeping the “y” position.
position.x = Mathf.Clamp(target.x, -maxOffset, maxOffset);
Here we change the “x” value of our local variable. If the target’s “x” value is in between the positive and negative maximum offset, then it will return the unmodified target “x” location. Otherwise, the returned value will be clamped, so it can never be larger or smaller than the range we specified. Note that the method we used here takes three parameters: an initial value, a minimum value and a maximum value. When there is more than one parameter, we separate them with commas.
rb.MovePosition(position);
The final statement uses a method on the rigid body to move our paddle to its new location. Since we use this, instead of the Transorm component, it will also apply any physics collisions that may need to occur between the starting and ending location of the paddle.
Connect The Script
Head back to Unity, then attach the Paddle script as a component on our Paddle GameObject.
Press Play and observe how the Paddle’s position is controlled by the mouse position. It is actually starting to feel a bit like a game, even though there are no real goals or penalties in place.
Summary
In this lesson we worked with the final type of rigid body, a kinematic rigid body. We covered a few useful methods including “Update”, converting from screen space to world space, and clamping values. We also showed how to cache references to components to help optimize repeated use.
If you’d like you can also download the completed project for this lesson here.
If you find value in my blog, you can support its continued development by becoming my patron. Visit my Patreon page here. Thanks!