Saving and loading high scores in Unity2d - c#

What I've done so far is set a score to increase by each second in gameplay, get the score to show within the game scene and then set the highscore to be equal to the score if the score is greater than the highscore. This is my code so far:
bool gameOver;
public Text scoreText;
public Text highScoreText;
int score;
int highScore;
// Use this for initialization
void Start () {
score = 0;
highScore = 0;
InvokeRepeating ("scoreUpdate", 1.0f, 1.0f);
gameOver = false;
}
// Update is called once per frame
void Update () {
scoreText.text = "★" + score;
highScoreText.text = "★" + highScore;
}
public void gameOverActivated() {
gameOver = true;
if (score > highScore) {
highScore = score;
}
PlayerPrefs.SetInt("score", score);
PlayerPrefs.Save();
PlayerPrefs.SetInt("highScore", highScore);
PlayerPrefs.Save();
}
void scoreUpdate() {
if (!gameOver) {
score += 1;
}} }
"game over" is equal to true when this code happens:
void OnCollisionEnter2D (Collision2D col) {
if (col.gameObject.tag == "enemyPlanet") {
ui.gameOverActivated ();
Destroy (gameObject);
Application.LoadLevel ("gameOverScene2");
}
}
What I want is at this point (when the objects collide and game over is true) for the score to be saved, then the game over scene is loaded. How do I save the score at game over, then load it in the game over scene along with a saved highscore??

There are multiple ways you can do this, two of the most obvious ways to do it if you are only persisting the score for that session is to store it in a Static Class or a Singleton. These classes will persist for however long you need them to, regardless of scene loading, so be careful how you manage the information in them.
One example of a static class implementation would be:
public static class HighScoreManager
{
public static int HighScore { get; private set; }
public static void UpdateHighScore(int value)
{
HighScore = value;
}
}
If you are looking to persist the data for a longer amount of time you will need to look at this
I hope this helps!

Related

When I add a score, the scoreText just rapidly displays the scores added to itself

I am a newbie and I am making this android game that if the player has destroyed a meteor, a score is added to its score, well the problem is that I want to display the score in my scoreText, but whenever I initialize it in my Update(), it rapidly adds the score in my scoreText. I just cant figure out how to properly add the score to my scoreText This is my game manager script
public class GameManager : MonoBehaviour
{
public static int displayScores;
public int displayTheScore;
public Text scoreText;
// Start is called before the first frame update
void Start()
{
scoreText.text = "" + displayScores;
}
void Update(){
scoreText.text = "" + displayScores;
displayScores += Meteor.displayScore;
}
}
And this is the script to making the conditions that if the meteor is detroyed, a score is added to displayScore depending on the hits to the meteor
public class Meteor : MonoBehaviour
{
public int maxHealth;
public int currentHealth;
public float speed;
public int hits = 0;
public int score = 100;
public static int displayScore;
public int display;
public int currentHealthChecker;
public static int counter;
public Health healthBar;
public GameObject canvas;
public Transform effect;
// Start is called before the first frame update
void Start()
{
currentHealth = maxHealth;
healthBar.setMaxHealth(maxHealth);
}
// Update is called once per frame
void Update()
{
transform.Translate(Vector2.down * speed * Time.deltaTime);
}
public void OnTriggerEnter2D(Collider2D other){
if(other.transform.tag == "bullet"){
hits++;
canvas.SetActive(true);
currentHealth--;
currentHealthChecker = currentHealth;
healthBar.setHealth(currentHealth);
display = displayScore;
if(currentHealth <= 0){
displayScore = score * hits;
Instantiate(effect, other.transform.position, other.transform.rotation);
Destroy(this.gameObject);
counter++;
canvas.SetActive(false);
}
Destroy(other.gameObject);
}
if(other.transform.tag == "bottom"){
Destroy(this.gameObject);
}
}
}
you are initializing in update method, that why it keeps adding rapidly because update is called every frame. instead of adding in update, add the score value in ontriggerenter2d method.
public void OnTriggerEnter2D(Collider2D other){
if(other.transform.tag == "bullet"){//add score}

Storing Highscore in Unity C# code not working

So, I've been trying to store highscore of my player but no matter how much I try the return is 0.
Here's the score setting
highScore = playerScoref();
if(PlayerPrefs.GetFloat("Score") < highScore) {
PlayerPrefs.SetFloat("Score", highScore);
}
PlayerPrefs.Save();
}
and this is where I get back the code
Debug.Log("GAME OVER");
highScore = PlayerPrefs.GetFloat("Score");
Debug.Log(highScore);
I think you need to do something like this
public class Test : MonoBehaviour {
private int ingameScore;
private int highScore;
private bool gameOver;
private bool callOnce;
void Start() {
if (PlayerPrefs.HasKey("HighScore")) {
highScore = PlayerPrefs.GetInt("HighScore");
}
else {
//creating the key for highscore
PlayerPrefs.SetInt("HighScore", 0);
highScore = 0;
}
}
void Update() {
//if player lost the game set gameover boolean to true
//and use callOnce boolean to call these block only once and only for one frame
//to avoid extra cpu usage
if (gameOver && !callOnce) {
//and check if player collected higher score then highscore is and assign it
//to playerpref's highscore key
if(ingameScore > highScore) {
PlayerPrefs.SetInt("HighScore", ingameScore);
}
callOnce = true;
}
}
}

How do I get the score to reset

Once the player dies and starts the game, the score is not resetting and staying as the previous score. I would like the score to reset once the player dies or leaves the game. How do you do this?
public class ScoreScript : MonoBehaviour {
public static int scoreValue = 0;
Text score;
// Use this for initialization
void Start () {
score = GetComponent<Text>();
}
// Update is called once per frame
void Update () {
score.text = "Score: " + scoreValue;
}
}
score.text is storing the evaluated value of Score: and whatever is stored in scoreValue at the time Update() is called. None of your code ever updates scoreValue from what you've shown.
Also be aware of scoreValue being static, be sure that accurately reflects your intention (e.g. is scoreValue a property of the ScoreScript class or each instance of it?). Note that score is not static, and I would expect both of those to have the same behavior (either both static or not).
i.e. something like
public class ScoreScript : MonoBehaviour {
public static int scoreValue = 0;
Text score;
// Use this for initialization
void Start () {
score = GetComponent<Text>();
}
// Update is called once per frame
void Update () {
score.text = "Score: " + scoreValue;
}
void ScoreReset() {
scoreValue = 0;
}
void AddPoints(int points) {
scoreValue += points;
}
}
If you load the scene after player die scoreValue will be 0 cause as I see that you assign 0 in your above code.

Score is not increasing

I created a simple game in which the player collides with the enemy, and the score will increase by one. How to do it correctly?
Below is my code:
public class Bird : MonoBehaviour {
public GameObject deathparticales;
public Vector2 velocity = new Vector2(-2, 0);
public float range = 5;
public int score;
private string scoreText;
// Use this for initialization
void Start()
{
score = 0;
rigidbody2D.velocity = velocity;
transform.position = new Vector3(transform.position.x, transform.position.y - range * Random.value, transform.position.z);
}
// Update is called once per frame
void Update () {
// Die by being off screen
Vector2 screenPosition = Camera.main.WorldToScreenPoint(transform.position);
if (screenPosition.x < -10)
{
Die();
}
scoreText = "Score: " + score.ToString();
}
void OnGUI ()
{
GUI.color = Color.black;
GUILayout.Label(scoreText);
}
// Die by collision
void OnCollisionEnter2D(Collision2D death)
{
if(death.transform.tag == "Playercollision")
{
score++;
Destroy(gameObject);
Instantiate(deathparticales,transform.position,Quaternion.identity);
}
}
void Die()
{
Application.LoadLevel(Application.loadedLevel);
}
}
Problem
You were trying to update the score inside everyone of those Birds.
Solution
You need a class whose only purpose is to handle the score.
public class ScoreManager : MonoBehaviour
{
private int score = 0;
private static ScoreManager instance;
void Awake()
{
instance = this;
}
public void incrementScore(int amount)
{
score += amount;
}
public static ScoreManager getInstance()
{
return instance;
}
void OnGUI ()
{
string scoreText = "Score: " + score.ToString();
GUI.color = Color.black;
GUILayout.Label(scoreText);
}
}
Then every time you want to update the score you call ScoreManager from another class, like this:
ScoreManager.getInstance().incrementScore(10);
If all the code is from same script, the problem is that you are increasing the score of one instance of Bird class and then killing that instance:
score++;
Destroy(gameObject);
The gameObject refers to that gameobject into which this instance of Bird class is attached to.
Score variable is just public which means that every instance of Bird has their own, but you can access the variable from other scripts. If you want to have just one score variable shared with all Birds you could make the variable static.
But if you have multiple birds, all of them are going to call OnGUI function and draw the value to the screen. So it might be better idea to change your design and move the score to some other gameObject.

How to keep the users score and load it in the next scene?

The problem: I need the score that the user gets to be passed into the next scene, nothing complex just so it can say something like 'well done you scored' + Score. The game structure consists of three scenes, start, play, end. I need the score to be available from the play scene to the end scene.
The question: How do i do this? I've looked over singletons & DontDestroyOnLoad functions but im not sure how to use them or what to attach them too and what game objects to save.
public class Score : MonoBehaviour
{
public int score = 0;
void Awake ()
{
InvokeRepeating("increaseScore", 1, 1);
}
void Update ()
{
score++;
// Set the score text.
guiText.text = "Score: " + score;
}
}
This is the code for my scoring if it helps.
You could use PlayerPrefs.SetInt and PlayerPrefs.GetInt:
// Save score to prefs before scene is destroyed
PlayerPrefs.SetInt("score", score);
And then:
// Load score when new scene is loaded
score = PlayerPrefs.GetInt("score");
Alternatively, within your Score class' Awake function, use DontDestroyOnLoad so that its GameObject won't be destroyed:
DontDestroyOnLoad(gameObject);
Create a static class with a static variable for the score. This is the easiest solution and you don't need to use playerPrefs.
public static ScoreManager
{
private static int score = 0;
public static void setScore(int s)
{
score = s;
}
public static int getScore()
{
return score;
}
}
Static classes stay alive throughout the execution of the whole program, no matter what scene you go to.

Categories

Resources