Score system, saving high-scores and reactive ending


The Aim

I had 2 score systems for BICS. The first script deals with the individual score in every level: Each level score starts at 200 upon starting the level, and whenever a block is hit, it will minus/ add the corresponding number to the score.

The second script deals with the total score added from all the levels. I did not have the first script value update into the total score value after each level. Instead I had manually input a different value for the total score counter: 200 * 10(my number of levels) and had it update the same time the individual level score updates. 

Since the total score should be scripted such that the change of score in the level will be reset to zero every-time a player replayed a level, I added an additional component to that script. This script is part of a text gameObject and the child of a Canvas. The canvas was marked DontdestroyonLoad and it was placed in the first level of the game.

On the ending page of BICS, I provided a high-score saver that only display the highest scorer (who saved their name into the page) and their name.

The ending image for BICS also changes depending on whether the player gets a score of 50% and above or below 50%.

The score Code

1. Normal score counter for individual level: I stored the scores in a scripted called "ScoreCounter" and displayed it in the Text UI gameObject it was attached to.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class ScoreCounter : MonoBehaviour
{
    public static int scoreValue =200;
    public float playerscore= 200;
    Text score;
    //remember to drag the text gameObject to the inspector
    void Start()
    {
        score = GetComponent<text>();
    }
    void Update()
    {
        score.text = "$" + scoreValue;
        playerscore = scoreValue;
        //text gameObject will read: "$200" initially when level has loaded
        if(scoreValue < 10)
        {
            SceneManager.LoadScene("TooPoor");
            // A new scene for the fail state of the game will load if score is $0 
            //You can write "if(scoreValue ==0)" to be more specific
            Debug.Log("YouLostAllYourMoney");
            //confirmation that script is working, printed in the debug log.
        }
    }
    private void OnLevelWasLoaded(int level)
    {
        scoreValue = 200;
    }
    //when level is restarted, the score will reset to 200
}

2. Total score counter script called "TOTALScore" to carry over all the levels: This script is attached to a Text UI, which is then attached under a Canvas UI element as the Canvas' child. The script calls a Bool made in another script called "Restart", which allows players to restart the level, a state that is tracked via the bool. (whether Restart.restarting = true/false)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class TOTALscore : MonoBehaviour
{
    public static int TotalscoreValue =200*10;
    public float Totalplayerscore = 200 * 10;
    //level score times the number of levels made
    Text score;
    //this line below is to record change in level score for reset
    public static int changeinscore;
    //
    void Start()
    {
        score = GetComponent<text>();
    }
    void Update()
    {
        score.text = "Total $" + TotalscoreValue;
        Totalplayerscore = TotalscoreValue;
        //text gameObject will read: "Total $2000" initially when level_1 has loaded
    }
    //make restart also restart value of only that scene
    private void OnLevelWasLoaded(int level)
    {
        if (Restart.restarting)//bool restarting= true
        {
            TotalscoreValue = TotalscoreValue + changeinscore;//added change back to total score
            changeinscore = 0;//reset the change in score
            Restart.restarting = false;//reset the bool
        }
        else
        {
            Totalplayerscore = TotalscoreValue;//this line MAY be redundant
            Restart.restarting = false;//also may be redundant
            Scene currentScene = SceneManager.GetActiveScene();
            string sceneName = currentScene.name;
            if (sceneName == "Level_1"|| sceneName == "Level_2" ||
                sceneName == "Level_3" || sceneName == "Level_4" ||
                sceneName == "Level_5" || sceneName == "Level_6" ||
                sceneName == "Level_7" || sceneName == "Level_8" ||
                sceneName == "Level_9" || sceneName == "Level_10")
            {
                changeinscore = 0;
                //this makes sure that, in the case that the player moved to the next level without restarting,
                //the change in score also resets so that only change in score in the newest level is stored 
            }
            if (sceneName == "Introduction")//this is an additional scene I have before level one
            {
                changeinscore = 0;
                TotalscoreValue = 200 * 10;
                //this ensures that someone restarting the game from, say, level 7, and going back from the very start
                //of the game, will be able to have their total score reset to the highest score again
                //alternatively, you could have put sceneName == "level1" directly. that will work too...
            }
        }
    }
}

Script storing the "restarting" bool:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Restart : MonoBehaviour
{
    public string prevScene;
    public static bool restarting;
    public void RestartGame()
    {
        SceneManager.LoadScene(prevScene); // loads prev level scene
        Debug.Log("restart");
        restarting = true;
    }
}

Script in Canvas (parent to the total score counter):

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DontDestory : MonoBehaviour
{
    public GameObject scoreCanvas;
    void Awake()
    {
        DontDestroyOnLoad(scoreCanvas);
    }
}

The high score saver Code

This code was connected to quite a number of gameObjects in the scene:


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class AddingScore : MonoBehaviour
{
    public Text highScore;
    public Text playerScore;
    public Text playerName;
    //input for name below
    public InputField playername;
    private void Start()
    {
        //highScore = GetComponent<text>();
        //playerScore = GetComponent<text>();
        //playerName = GetComponent<text>();
        highScore.text = "HighestScore: $" + PlayerPrefs.GetInt("HighScore", 0).ToString();
        //fetch current highest score (either a saved number or 0)
        playerName.text = "by " + PlayerPrefs.GetString("playerName", "anon");
        //fetch current highest scorer name (either a saved name or anon)
        playerScore.text = "Your Final Score: $" + TOTALscore.TotalscoreValue + "/$2000";
        //text display total score of current player
    }
    public void SaveHighscore()//put this function to the OnClick of the button
    {
        playerScore.text = "Your Final Score: $" + TOTALscore.TotalscoreValue.ToString() + "/$2000";
        //text display total score of current player
        if (TOTALscore.TotalscoreValue > PlayerPrefs.GetInt("HighScore", 0))//if current player score better
        {
            PlayerPrefs.SetInt("HighScore", TOTALscore.TotalscoreValue);//save new
            highScore.text = "HighestScore: $" + TOTALscore.TotalscoreValue.ToString();//change text
            PlayerPrefs.SetString("playerName", playername.text);//save new
            playerName.text = "by " + playername.text.ToString();//change text
        }
    }
}

Lastly, I implemented a reset score system in case we need to reset the highscore completely:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class ResetHScore : MonoBehaviour
{ 
    public void ResetScorenName()//place in OnClick() on the button this script is attached to
    {
        PlayerPrefs.DeleteKey("HighScore");
        PlayerPrefs.DeleteKey("playerName");
        SceneManager.LoadScene("Leaderboard"); // loads current scene
        Debug.Log("refreshed values");
    }
}

Reactive ending image Code

There are two different sprites for the clerk in the ending picture: "sadlad" for scorers under half score, and "oklad" for scorers over half score:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class FinalScore : MonoBehaviour
{
    Text score;
    //drag the swapping parts into the gameObjects slots
    public GameObject sadlad;
    public GameObject oklad;
    // print
    void Start()
    {
        score = GetComponent<text>();
        score.text = "Total money left= $" + TOTALscore.TotalscoreValue + "/$2000";
        if (TOTALscore.TotalscoreValue < 1000)
        {
            sadlad.GetComponent<spriterenderer>().enabled = true;
            oklad.GetComponent<spriterenderer>().enabled = false;
        }
        else
        {
            sadlad.GetComponent<spriterenderer>().enabled = false;
            oklad.GetComponent<spriterenderer>().enabled = true;
        }
    }
}

"sadlad"

if (TOTALscore.TotalscoreValue < 1000)
        {
            sadlad.GetComponent<spriterenderer>().enabled = true;
            oklad.GetComponent<spriterenderer>().enabled = false;
        }


"oklad"

else //(TOTALscore.TotalscoreValue > 1000)
        {
            sadlad.GetComponent<spriterenderer>().enabled = false;
            oklad.GetComponent<spriterenderer>().enabled = true;
        }

That's all for now! In the next post, I'll share how I did the code for the blue blocks/most common blocks.

Get Bull in a china shop

Leave a comment

Log in with itch.io to leave a comment.