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
Bull in a china shop
A bull breaks into your China Shop!
More posts
- First time doing PopupsMar 14, 2020
- Making the Blocks and BallMar 14, 2020
- BICS postmortemMar 11, 2020
- BICS ver.1.3 OverviewMar 05, 2020
Leave a comment
Log in with itch.io to leave a comment.