In this part we will create a Sound Manager which will hold and play our sound effects. We will also write the C# code required to make our ball ricochet off of paddles, walls and goals.
Because many people asked I will also use the Windows version of Unity in this tutorial and show you how to create our sprites using Gimp. This tutorial series isn’t just about Pong. I will make numerous other games including games like Space Invaders, Pacman, Tetris, Mario and others. If there is a 2D game you’d like to see tell me and I’ll see what I can do.
I’ll finish Pong in the next video and will cover the following topics : Collision Detection, Animation, AI Controlled Competitors, Physics, Keyboard Input, Unity User Interfaces, Splash Screens, Sound Effects, Background Music, Build Settings and more.
If you like tutorials like this consider donating a $1 on Patreon.
[googleplusone]
Code From the Tutorial
Ball.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Ball : MonoBehaviour {
// Balls default movement speed
public float speed = 30;
// The balls Rigidbody component
private Rigidbody2D rigidBody;
// Used to play sound effects
private AudioSource audioSource;
// Use this for initialization
void Start () {
// Get reference to the ball Rigidbody
rigidBody = GetComponent<Rigidbody2D>();
// When the ball is created move it to
// the right (1,0) at the desired speed
rigidBody.velocity = Vector2.right * speed;
}
// Called every time a ball collides with something
// the object it hit is passed as a parameter
void OnCollisionEnter2D(Collision2D col)
{
// If the LeftPaddle or RightPaddle hit the
// ball simulate the ricochet
if ((col.gameObject.name == "LeftPaddle") || (col.gameObject.name == "RightPaddle"))
{
HandlePaddleHit(col);
}
// WallBottom or WallTop
if ((col.gameObject.name == "WallBottom") || (col.gameObject.name == "WallTop"))
{
// Play the sound effect
SoundManager.Instance.PlayOneShot(SoundManager.Instance.wallBloop);
}
// LeftGoal or RightGoal
if ((col.gameObject.name == "LeftGoal") || (col.gameObject.name == "RightGoal"))
{
// Play the sound effect
SoundManager.Instance.PlayOneShot(SoundManager.Instance.goalBloop);
// TODO Update Score UI
// Move the ball to the center of the screen
transform.position = new Vector2(0, 0);
}
}
void HandlePaddleHit(Collision2D col)
{
// Find y for the ball vector based
// on where the ball hit the paddle
// Above the center y angles up
// Below the center y angles down
float y = BallHitPaddleWhere(transform.position,
col.transform.position,
col.collider.bounds.size.y);
// Vector ball moves to
Vector2 dir = new Vector2();
// Go left or right on the x axis
// depending on which panel was hit
if(col.gameObject.name == "LeftPaddle")
{
dir = new Vector2(1, y).normalized;
}
if (col.gameObject.name == "RightPaddle")
{
dir = new Vector2(-1, y).normalized;
}
// Change the velocity / direction of ball
// You assign a vector to velocity
rigidBody.velocity = dir * speed;
// Play sound effect
SoundManager.Instance.PlayOneShot(SoundManager.Instance.hitPaddleBloop);
}
// Find y for the ball vector based
// on where the ball hit the paddle
float BallHitPaddleWhere(Vector2 ball, Vector2 paddle, float paddleHeight)
{
return (ball.y - paddle.y) / paddleHeight;
}
}
SoundManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SoundManager : MonoBehaviour {
// Holds the single instance of the SoundManager
// that can be accessed from any other script
public static SoundManager Instance = null;
// Will hold the sound effects
public AudioClip goalBloop;
public AudioClip lossBuzz;
public AudioClip hitPaddleBloop;
public AudioClip winSound;
public AudioClip wallBloop;
// Refers to the AudioSource added to
// SoundManager to play sound effects
private AudioSource soundEffectAudio;
// Use this for initialization
void Start () {
// This is a singleton that makes sure you only
// ever have one SoundManager
// If someone tries to create another destroy it
if (Instance == null)
{
Instance = this;
} else if(Instance != this)
{
Destroy(gameObject);
}
/* YOU ACTUALLY DON'T NEED THIS
AudioSource[] sources = GetComponents<AudioSource>();
foreach(AudioSource source in sources)
{
if(source.clip == null)
{
soundEffectAudio = source;
}
}
*/
// Use this instead
AudioSource theSource = GetComponent ();
soundEffectAudio = theSource;
}
// Any script can call this to play a sound effect
public void PlayOneShot(AudioClip clip)
{
soundEffectAudio.PlayOneShot(clip);
}
}
MovePaddle.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MovePaddle : MonoBehaviour {
// Speed paddles move
public float speed = 30;
// Called each time the frame updates
// but this is used instead of update
// when using Rigidbody
void FixedUpdate()
{
// Check to see if keys associated with
// vertical movement is being pressed
float vertPress = Input.GetAxisRaw("Vertical");
// Move the paddle in the y direction
// depending on the keys pressed and
// the desired speed
GetComponent<Rigidbody2D>().velocity = new Vector2(0, vertPress) * speed;
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}