
In this Unit, I programmed a game to test the player’s reflexes, where the goal is to click and destroy objects randomly tossed in the air before they can fall off the screen. In creating this prototype, I learned how to implement a User Interface – or UI – into my projects. I added a title screen with a difficulty select menu that allows the user to control how challenging the gameplay is. In addition, I added a score display that will track how many points the player has earned, and a Game Over screen, which will allow the player to restart and try again.
In learning these skills, I found out what it means to create a fully “playable” experience that the user can enjoy from start to finish without having to restart the application to try it again. Give it a try at this link: https://meta.dwdenney.com/beachballsmash/

Project Outcomes:
A list of three good target objects and one bad target object will spawn in a random position at the bottom of the screen, thrusting themselves into the air with random force and torque. These targets will be destroyed when the player clicks on them or they fall out of bounds.
A “Score: “ section will display in the UI, starting at zero. When the player clicks a target, the score will update and particles will explode as the target is destroyed. Each “Good” target adds a different point value to the score, while the “Bad” target subtracts from the score.
When a “good” target drops below the sensor at the bottom of the screen, the targets will stop spawning and a “Game Over” message will display across the screen. Just underneath the “Game Over” message will be a “Reset Game” button that reboots the game and resets the score, so the player can enjoy it all over again.

Starting the game will open to a beautiful menu, with the title displayed prominently and three difficulty buttons resting at the bottom of the screen. Each difficulty will affect the spawn rate of the targets, increasing the skill required to stop “good” targets from falling.
C# Code Samples
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Target : MonoBehaviour
{
private Rigidbody targetRB; // set in the start method
private GameManager gameManager; // set in the start method
private float minSpeed = 12;
private float maxSpeed = 16;
private float maxTorque = 10;
private float xRange = 4;
private float ySpawnPos = -2;
public int pointValue;//this will be set for each prefab separatelyin the ui
public ParticleSystem explosionPaticle;//this will be set for each prefab via the ui also
// Start is called before the first frame update
void Start()
{
// get the target's rigid body component to work with
targetRB = GetComponent<Rigidbody>();
// move the target rb in a random speed upward
targetRB.AddForce(RandomForce(), ForceMode.Impulse);
//spin the target in a random speed/direction
targetRB.AddTorque(RandomTorque(), RandomTorque(), RandomTorque(), ForceMode.Impulse);
// spawn the target in a random position
transform.position = RandomSpawnPos();
//refer to the game manager script for using the update score funtion
gameManager = GameObject.Find("GameManager").GetComponent<GameManager>();
}
// Update is called once per frame
void Update()
{
}
private void OnMouseDown()
{
if (gameManager.isGameActive)
{
Destroy(gameObject);
gameManager.UpdateScore(pointValue);
Instantiate(explosionPaticle, transform.position, explosionPaticle.transform.rotation);
}
}
private void OnTriggerEnter(Collider other)
{
Destroy(gameObject);
if (!gameObject.CompareTag("Bad")) { gameManager.GameOver(); }
}
Vector3 RandomForce()
{
return Vector3.up * Random.Range(minSpeed, maxSpeed);
}
float RandomTorque()
{
return Random.Range(-maxTorque, maxTorque);
}
Vector3 RandomSpawnPos()
{
return new Vector3(Random.Range(-xRange, xRange), ySpawnPos);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
//create empty list of game targets to be assigned via UI
public List<GameObject> targets;
public float spawnRate = 1.0f;
private int score;
// assigned in the ui
public TextMeshProUGUI scoreText;
public TextMeshProUGUI gameOverText;
public Button restartButton;
public GameObject startScreenAudio;// assigned in ui
public GameObject gamePlayAudio;// assigned in ui
public GameObject gameOverAudio;// assigned in ui
public bool isGameActive;
public GameObject titleScreen; // assingned in the ui
// Start is called before the first frame update
void Start()
{
startScreenAudio.SetActive(true);
}
// Update is called once per frame
void Update()
{
}
IEnumerator SpawnTarget()
{
while (isGameActive)
{
yield return new WaitForSeconds(spawnRate);
int index = Random.Range(0, targets.Count);
Instantiate(targets[index]);
}
}
public void UpdateScore(int scoreToAdd)
{
score += scoreToAdd;
scoreText.text = "Score: " + score;
}
public void GameOver()
{
gameOverText.gameObject.SetActive(true);
restartButton.gameObject.SetActive(true);
isGameActive = false;
gamePlayAudio.SetActive(false);
gameOverAudio.SetActive(true);
}
public void RestartGame()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
public void StartGame( int difficulty)
{
startScreenAudio.SetActive(false);
gamePlayAudio.SetActive(true);
spawnRate /= difficulty;
isGameActive = true;
score = 0;
UpdateScore(0);
StartCoroutine(SpawnTarget());
titleScreen.gameObject.SetActive(false);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DifficultyButton : MonoBehaviour
{
private Button button;// set in the start method
private GameManager gameManager; // set in the start method
public int difficulty; // set in the ui for each button separately
// Start is called before the first frame update
void Start()
{
button = GetComponent<Button>();
button.onClick.AddListener(SetDifficulty);
//refer to the game manager script for using the start game function
gameManager = GameObject.Find("GameManager").GetComponent<GameManager>();
}
// Update is called once per frame
void Update()
{
}
void SetDifficulty()
{
Debug.Log(gameObject.name + " was clicked");
gameManager.StartGame(difficulty);
}
}