How to implement a reward-based system in Unity (Part 6)

Implementing a reward-based system in Unity involves creating a system where the player receives rewards for specific actions or achievements within the game.

This Answer is part of the introductory series on how to build a first-person shooter game using Unity.

Let’s dive into what we’ll be creating together in this Answer.

Let’s name our game “Shoot Box,” which has a 15-second duration. The game’s goal is to shoot boxes with bullets, and the coin count will vary based on the following factors:

Destroy friend box: -1

Destroy enemy box: +1

Step 1: Set up the scene

First, create a new Unity 3D project or open an existing one. Ensure the scene includes a “Main Camera” and a directional light. This Answer builds upon the scene covered in the Randomly spawn GameObjects within a confined boundary in Unity Answer.

Step 2: Define the rewards and trigger reward events

First, decide on the rewards we want to offer players. These rewards can include points, coins, power-ups, new items, or any other in-game benefits.

In our game, we will increment the coin count by +1 when the player hits the “Enemy” box and decrease it by -1 if they hit the “Friend” box within a given time.

Creating the GameScreenUI

  • Right-click the “Hierarchy” panel and navigate to “UI” > “Canvas” to create a new canvas. This canvas will serve as the primary layer for the UI elements. Name this canvas “GameScreenUI.”

  • Within “GameScreenUI,” add “TimeCounter.”

    • Right-click “GameScreenUI.”

    • Choose “UI” > “Text - TextMeshPro.”

    • Place “TimeCounter” in the top left corner of the canvas.

  • Next, add “CoinCounter.”

    • Follow the same steps to add another “Text - TextMeshPro.”

    • Position “CoinCounter” appropriately, typically on the top right.

  • To visually represent the coins, add a coin image:

    • Right-click “GameScreenUI.”

    • Select “UI” > “Image” to add an image element.

    • Place this image next to the “CoinCounter.”

    • Rename this image to “Coin.”

UI added to the scene
UI added to the scene

Creating the EndScreenUI

  • Right-click the “Hierarchy” panel and select “UI” > “Canvas” to create a second canvas. Name this new canvas “EndScreenUI.” It will be dedicated to the end screen of our game.

  • On the “EndScreenUI” canvas, start by adding an image UI element:

    • Right-click “EndScreenUI.”

    • Choose “UI” > “Image” to add the background image.

  • Next, add “GameOverText.”

    • On the same canvas, add “GameOverText” by right-clicking “EndScreenUI” and selecting “UI” > “Text - TextMeshPro.” This will display the end-of-game message.

  • Next, add “CoinEarned.”

    • Follow the same steps to add another “Text - TextMeshPro.”

    • Position “CoinCounter” appropriately on the image.

  • To visually represent the coins, add a coin image.

    • Right-click “EndScreenUI.”

    • Select “UI” > “Image” to add an image element.

    • Place this image next to “CoinEarned.”

    • Rename this image to “Coin.”

EndScreenUI
EndScreenUI

Step 3: Create a game/reward manager

Write a C# script to manage the coins and the UI. Attach this script to an empty GameObject in the scene or create a dedicated manager object for it and name it “GameManager.” Add the following script to that GameObject:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class GameManager : MonoBehaviour
{
[SerializeField] private float totalTime = 5f; // Total time for the game in seconds
[SerializeField] private TMP_Text timeText;
[SerializeField] private TMP_Text endScreenCoinText;
[SerializeField] private GameObject endScreenUI;
[SerializeField] private GameObject gameScreenUI;
[SerializeField] private TMP_Text coinText;
private float currentTime;
private bool isGameOver = false; // Flag to indicate if the game is over
private int coinCount = 0;
void Start()
{
endScreenUI.SetActive(false);
gameScreenUI.SetActive(true);
currentTime = totalTime;
UpdateTimeText();
UpdateCoinText();
}
void Update()
{
if (!isGameOver && currentTime > 0f)
{
currentTime -= Time.deltaTime;
UpdateTimeText();
}
else if (!isGameOver)
{
EndGame();
}
}
void UpdateCoinText()
{
coinText.text = coinCount.ToString();
}
public void IncreaseCoinCount()
{
coinCount++;
UpdateCoinText();
}
public void DecreaseCoinCount()
{
coinCount--;
UpdateCoinText();
}
void UpdateTimeText()
{
timeText.text = $"Time left: {Mathf.Ceil(currentTime)}";
}
void EndGame()
{
endScreenUI.SetActive(true);
gameScreenUI.SetActive(false);
endScreenCoinText.SetText(coinText.text);
isGameOver = true;
// You can show the end screen here
Debug.Log("Game Over!");
Time.timeScale = 0f; // Pause the game
}
}

The script above is responsible for managing the game’s timer, coin count, and end screen. It utilizes serialized fields to configure UI elements and game parameters within “Inspector.” The game begins with a specified total time, determined by totalTime. During gameplay, the script updates the time and coin text. Once the timer reaches zero or the game ends, the end screen displays with the coin count. Pausing the game is possible by setting Time.timeScale to 0. This script also provides methods for increasing and decreasing the coin count, making it suitable for games with collectible coins.

The explanation for the two main events are as follows:

Coin events

  • coinCount: It holds the count of collected coins during the game.

  • IncreaseCoinCount(): It is a public method to increase coinCount and update the coin text.

  • DecreaseCoinCount(): It is a public method to decrease coinCount and update the coin text.

Time events

  • UpdateTimeText(): It updates the time text to display the remaining time.

  • Start(): It initializes the game state, time, and coin text.

  • Update(): It decreases currentTime, updates time text, and ends the game if time runs out.

  • EndGame(): It shows end screen UI, logs “Game Over!”, and pauses the game.

Step 4: Attach the script

Attach the script to the “GameManager” component and drag and drop the required fields as shown below:

The GameManager’s Inspector window
The GameManager’s Inspector window

Play here!

Note: Click the “Run” button below to start the game. Once the game is rendered, interact with it by clicking the “Output” screen. Alternatively, you can access the game by clicking the link provided after the “Your app can be found at:” text.

import React from 'react';
require('./style.css');

import ReactDOM from 'react-dom';
import App from './app.js';

ReactDOM.render(
  <App />, 
  document.getElementById('root')
);

Conclusion

We’ve reached the conclusion of our exciting series on crafting a basic FPS game in Unity. Throughout this journey, we’ve explored a range of essential techniques and features. Starting with the fundamentals of shooting game logic, we delved into the intricate process of implementing a dynamic weapon-switching system. We also ventured into the creative realm of designing a Martian-themed skybox, adding a unique atmospheric touch to our game environment.

Our journey didn’t stop there. We tackled the challenge of programming enemy GameObjects to be destroyed upon collision, adding a layer of realism and interactivity to the gameplay. Furthermore, we mastered the technique of randomly spawning GameObjects within confined boundaries, a crucial skill for keeping the game environment engaging and unpredictable.

Question

Can you create a multiplayer FPS game using the techniques learned in this series, and if so, what are the key considerations for ensuring smooth gameplay and player interaction?

Show Answer


Free Resources

Copyright ©2025 Educative, Inc. All rights reserved