Ball PhysicsLet’s start by giving the ball some physics behaviour. Physics is handled automatically by Unity, so we can get a lot of functionality for ‘free’ by using the physics engine.
The Play ButtonClick the Play button in the main Unity window (near the top of the screen in the centre). This runs the current scene, though at the moment nothing happens. That’s to be expected since we haven’t implemented anything yet. Press Play again to return to editing mode. If you make changes while in play mode those changes are undone when you exit play mode. This can be costly if you forget you’re in play mode and make changes! To remedy this you can make the Unity screen change colour when you’re in play mode. Go to Edit | Preferences… | Colors, then change the Play mode tint value. Test it out by going back to play mode.
Add a Rigidbody
What is a rigidbody 2d?When a GameObject has a rigidbody, the built-in physics engine in Unity acts upon it automatically, giving it mass (e.g. for gravity to work on it).
Add the componentAdd a RigidBody2D to the Ball GameObject:
- Select Ball in Hierarchy
- In Inspector click Add Component, select Physics 2D, then Rigidbody 2D.
Making the Ball BounceThe ball falls with a thud (forget for now that we don’t actually want the ball to fall ‘down’ the screen at all). Let’s make our ball bouncy, and while we’re at it we’ll make the paddles and walls bouncy too. For that we’ll need a physics material.
MaterialsA physics material gives physical properties to colliders. These properties affect interactions between different objects.
Create a Material
- In the Assets folder, create a new folder called Materials.
- In the Materials folder right-click and choose Create | Physics2D Material.
- Rename this new material to ‘BouncyMaterial’.
- Select BouncyMaterial in the Materials folder so it opens in Inspector.
- Change the Bounciness property to 1, and the Friction property to 0:
Apply the MaterialSelect Ball in Hierarchy, then drag the new material into the Material field in the Circle Collider 2D in Inspector: Now we want to make the walls bouncy too. Instead of doing it for all four walls we will simply make the prefab bouncy, which will then apply to each wall automatically.
- Select WallPrefab in the Prefabs folder (to open it in Inspector).
- Select the Materials folder and drag-and-drop the material from there to the prefab’s collider:
Defying GravityBecause Pong is top-down we don’t want gravity. Gravity is a constant downward force applied to anything with a rigidbody, and we can change it via the physics settings. From the menu choose Edit | Project Settings | Physics2D. A Physics2DSettings pane appears in the Inspector. At the top of this pane are the gravity settings, which are X:0 and Y: -9.81 by default, Change that Y value to 0 to remove the influence of gravity:
Hit Play to test the ‘game’. The ball should no longer fall. Exit Play mode.
ScriptingA script is a component like any other, so you create it like any other component.
- Create a new folder within the Assets folder called Scripts.
- Select the new folder, then right-click in the empty space and select Create | C# Script.
- A script appears in the folder. Rename this script to BallScript (don’t put an extension, just call it BallScript).
- Select Ball in Hierarchy
- Drag-and-drop the script file onto the blank area at the bottom of the Inspector window.
Modifying the ScriptI’ll go through the script piece-by-piece, and then give the whole script in one big lump at the end. If you have any issues, just copy the whole script and replace the entire contents with it. Add this code between the public class BallScript line and the void Start(): [code language=”csharp”] [SerializeField] float forceValue = 4.5f; [/code] This creates a field (a variable) called forceValue of type float. A float variable is a number with a decimal point, like 3.7. Note the ‘f’ after the value, which is required in C#. We will use forceValue to add a force to make the ball move. [SerializeField] tells Unity that this variable should be changeable via the Inspector window, so we can modify the force from Unity. Save that script (Ctrl-S in MonoDevelop). Unity doesn’t detect script changes until you have saved the script. Then go back to Unity and select Ball to see it in the Inspector:
You can change that 4.5 value in the Inspector, and it will apply to this instance of the script (you could attach this script to multiple balls, and give each one a unique force value). You can use this to tweak the game later. Instead of [SerializeField] you can make variables public, which has the same effect of making them accessible in Inspector, but you should avoid using public variables unless they need to be public. C# is case sensitive. If your code has errors, double-check the spelling and capitalisation. For example Rigidbody2D is very different to rigidbody2D, and if you call a variable myBody you can’t refer to it as MyBody. Next, add the following to the scripts below the forceValue variable: [code language=”csharp”] Rigidbody2D myBody; [/code] Then, in the Start() method, between the curly braces, add: [code language=”csharp”] myBody = GetComponent<Rigidbody2D>(); [/code] These lines create a new variable called myBody, and then assigns a reference to the ball’s GameObject’s rigidbody to that variable. After the Start() method has run we can then refer to rigidbody2D as ‘myBody’ for reasons we’ll investigate in future parts of this tutorial. Still in the Start() method, add the following line after the previous line (but still before the closing curly bracket): [code language=”csharp”] myBody.AddForce (new Vector2 (forceValue * 50, 50)); [/code] This line applies a force (a push) to the ball to get the game started. The Unity physics engine automatically calculates the ball’s movement. Save the script and go back to Unity and hit the Play button. The ball should start moving towards one of the player paddles, and bounce around a little. Now we’re getting somewhere!