Im creating a brick breaker game in Unity with one scene called Game that loads every single level based on data received from a json file.
I.E :
Once all bricks are destroyed from 1 level, the second level is
loaded in the same scene, and so on.
Once you lose, a "Lose" scene is loaded with a "Play Again" button.
I'd like the high score information to be retained in the player prefs even after you press the "Play Again" button.
But I'm a bit confused to how this works. This is my code for score:
using UnityEngine;
using UnityEngine.UI;
public class Score : MonoBehaviour
{
public Text scoreText;
public Text highScoreText;
private int score;
private int highScore;
void Start()
{
score = 0;
GetHighScore();
}
void Update()
{
UpdateScore();
SetHighScore();
GetHighScore();
}
// TO UPDATE HIGH SCORE
void SetHighScore()
{
if (score > highScore)
{
PlayerPrefs.SetInt("HighScore", score);
}
}
void GetHighScore()
{
highScore = PlayerPrefs.GetInt("HighScore");
highScoreText.text = "High score: " + highScore;
}
// TO UPDATE HIGH SCORE
// TO UPDATE SCORE
public void AddPoints(int points)
{
score = score + points;
UpdateScore();
}
void UpdateScore()
{
scoreText.text = "score: " + score;
}
// TO UPDATE SCORE
}
So far the score updates fine, but nothing happens to the high score. Any help is appreciated!
This method here achives nothing
void GetHighScore()
{
PlayerPrefs.GetInt("HighScore");
}
It should be
void GetHighScore()
{
highScore = PlayerPrefs.GetInt("HighScore");
}
And i dont see the point in calling it every frame in Update. Call it once in Start
Also, you may want to update highScore in SetHighScore
if (score > highScore)
{
highScore = score;
PlayerPrefs.SetInt("HighScore", highScore);
highScoreText.text = "high score: " + highScore;
}
Related
I'm currently recreating Jetpack Joyride and I'm having trouble with adding a highscore. I currently track my score on where my player is on the Y position and placing the score on a canvas. So I was wondering how do I save the score every time the score is higher that the highscore and when the scene resets.
This is what I currently use to track Y position of my player:
public class Score : MonoBehaviour
{
public Transform player;
public Text scoreText;
void Update()
{
scoreText.text = player.position.x.ToString("0" + "M");
}
}
There is multiple ways to implement high score.
You can use PlayerPrefs to store data in each scene and then load the data from storage and save again if the latest score is higher than the previous one.
You can create a global object which is not destroyed when new scenes load. In that object, you can attach a high score script that will keep track of the score.
Example Script for the 2nd Option
using UnityEngine;
using System.Collections;
public class MyCustomScript : MonoBehaviour {
public int score = 0;
void Awake()
{
GameObject[] objs = GameObject.FindGameObjectsWithTag("global");
if (objs.Length > 1)
{
Destroy(this.gameObject);
}
DontDestroyOnLoad(this.gameObject);
}
// Update is called once per frame
void Update () {
if( score < **getScore()** ){
score = getScore();
}
}
You should be saving that value when your player lose the game look at the comments I added to understand.
public class Score : MonoBehaviour
{
public Transform player;
public Text scoreText;
public Text highScoreText;
public float score;
bool lost;
private void Start()
{
HighScoreCheck();
}
void Update()
{
score = player.position.x;
//this is storing the score
scoreText.text = score.ToString("0" + "M");
highScoreText.text = PlayerPrefs.GetFloat("HighScore").ToString();
//this is showing the highest score recorded
LoseCheck();
}
private void HighScoreCheck()
{
if (!PlayerPrefs.HasKey("HighScore"))
//checking if this key has any value saved to it
{
Debug.Log("No High Score recorded Yet");
}
else
{
Debug.Log("HighScore is : " + PlayerPrefs.GetFloat("HighScore"));
}
}
private void LoseCheck()
{
if (lost)
{
if (score> PlayerPrefs.GetFloat("HighScore"))
{
PlayerPrefs.SetFloat("HighScore", score);
//this is how you save a float/int into a key that is stored in the device
}
else
{
Debug.Log("No new high score");
}
}
}
}
Im trying a basic multiplayer card game and want to sync the ammount of cards between the player. If a player draws a card the main deck loses one and depending on who drawed the card myDeck or the enmy deck gets one added.
At runtime if one player draws a card it works as intended but if the second player also draws a card the counter gets resetted.
public class Player : NetworkBehaviour{
private GameObject myHandText;
private GameObject enemyText;
private GameObject deckText;
private int deckCount;
private int myDeck;
private int enemyDeck;
private void Update()
{
if (Input.GetKeyDown("e"))
{
CmdDrawCard();
}
}
public override void OnStartClient()
{
base.OnStartClient();
myHandText = GameObject.Find("Me");
enemyText = GameObject.Find("Emeny");
deckText = GameObject.Find("Deck");
deckCount = 50;
myDeck = 0;
enemyDeck = 0;
RpcSetText();
}
[Command]
public void CmdDrawCard()
{
RpcSetDeck();
}
[ClientRpc]
void RpcSetDeck()
{
if (deckCount > 0)
{
deckCount--;
if (hasAuthority)
{
myDeck++;
}
else
{
enemyDeck++;
}
}
RpcSetText();
}
[ClientRpc]
void RpcSetText()
{
enemyText.GetComponent<Text>().text = "Enemy: " + enemyDeck;
myHandText.GetComponent<Text>().text = "My Deck: " + myDeck;
deckText.GetComponent<Text>().text = "Deck: " + deckCount;
}
}
I already tried too SyncVars but it changes nothing. It seems like each Player got two different counters for each variable.
I have quiz game which is the last game the score is come out.
the score is save and can show when the game is over, but when i replay the game the score don't return to zero
Here is my code in question and answer
public class QuestionAnswer : MonoBehaviour
{
public GameObject feedback_benar, feedback_salah;
public void answer(bool QuestionAnswer){
if (QuestionAnswer) {
feedback_benar.SetActive(false);
feedback_benar.SetActive(true);
int skor = PlayerPrefs.GetInt ("skor") + 10;
PlayerPrefs.SetInt ("skor", skor);
} else{
feedback_salah.SetActive(false);
feedback_salah.SetActive(true);
}
gameObject.SetActive (false);
transform.parent.GetChild(gameObject.transform.GetSiblingIndex()+1).gameObject.SetActive (true);
gameObject.SetActive (true);
}
}
and this in my score script code
public class Skor : MonoBehaviour
{
void Update()
{
GetComponent<Text> ().text = PlayerPrefs.GetInt ("skor").ToString();}}
}
}
If you want the score to reset each time you play the quiz simply don't save it, however if you want to implement a high score system you would do something like this.
private float score;
private void Update()
{
if (QuestionAnswered)
{
//Adds one to score if its right
score++;
}
}
void EndGame()
{
// score only gets saved if it is higher than the previously saved highscore
if (score > PlayerPrefs.GetFloat("HighScore", 0f))
{
PlayerPrefs.SetFloat("HighScore", score);
}
}
Then you simply call the endgame method when you want the game to end and it will compare highscore with score and if score is greater than saved highscore it will get updated.
I'm using playerprefs to save data through out scenes. Although I'm having troubles with saving this data when the application is closed. You see I have a IAP shop that gives the player a boomerang when they purchase one, the boomerang effect (done inside my script) is activated through a button. My problem is, is that playerprefs.haskey isn't saving my boomerang effect when I close the game and then reopening it. Although it does save my boomerang effect when through scenes. This is my script:
public bool forceActive = false;
public GameObject BoomerangOn, BoomerangOff;
public static int buttonCount = 0;
static int timesActivated = 0;
void Start()
{
if (PlayerPrefs.HasKey ("boomerangbutton")) {
buttonCount = PlayerPrefs.GetInt ("boomerangbutton");
BoomerangEffect();
}
}
void Update()
{
PlayerPrefs.SetInt("boomerangbutton", buttonCount);
}
public void Activated ()
{
if(timesActivated < BoomeerangText.score)
{
timesActivated++;
StartCoroutine(BoomerangEffect());
}
}
IEnumerator BoomerangEffect()
{
BoomerangOn.SetActive (true);
yield return new WaitForSeconds (10.0f);
BoomerangOn.SetActive (false);
BoomerangOff.SetActive (true);
yield return new WaitForSeconds (1f);
BoomerangOff.SetActive (false);
forceActive = false;
}
Second Edit
Okay I research a bit and linked up boomerang effect script with my boomerang text script. When the user purchase a boomerang from my IAP store, they will get 5 boomerangs, once clicked on, the boomerang text int will go down (like 5, 4, 3, 2 and 1 ) and so will my buttoncount int(that is why the timesactivaed is needed). However I change the Activated function to:
public void Activated ()
{
if (timesActivated < BoomeerangText.score) {
timesActivated++;
StartCoroutine (BoomerangEffect ());
}
}
So far it works regarding activating my boomerang effect when the application is closed, but when it gets to the last int (1) nothing happens, my effect doesn't takes place, so far this is my only problem.
Above is an updated version of what my code looks like now. And below is my Boomerang text script:
public static int score = 0; // The player's score.
public static int click = 1;
public GameObject button;
Text text; // Reference to the Text component.
// Use this for initialization
void Start()
{
if (PlayerPrefs.HasKey ("boomerangTextInt")) {
score = PlayerPrefs.GetInt("boomerangTextInt");
}
}
void Awake()
{
text = GetComponent<Text>();
}
public void Update()
{
SetScoreText();
PlayerPrefs.SetInt("boomerangTextInt", score);
}
void SetScoreText()
{
text.text = " " + score;
if (score <= 0)
{
text.text = "None";
button.GetComponent<Button>().interactable = false;
}
else if (score >= 1)
{
button.GetComponent<Button>().interactable = true;
}
// Set the displayed text to be the word "Score" followed by the score value.
}
public void MinusBoomerangText()
{
score -= click;
text.text = " " + score;
}
}
And in my purchasing script I have this:
public int scoreValue = 5;
if (String.Equals(args.purchasedProduct.definition.id, PRODUCT_5_BOOMERANG, StringComparison.Ordinal))
{
BoomerangEffect.buttonCount += 5;
BoomerangText.score += scoreValue;
Debug.Log("Purchase successfull");
}
Thank you.:)
You are not calling .Save() which means all changes to PlayerPrefs are only in memory and are not persisted to disk, which means the next time you start the application all previous changes are lost.
Try the following in your save function.
void Update()
{
PlayerPrefs.SetInt("boomerangbutton", buttonCount);
PlayerPrefs.Save();
}
Disclaimer : I am not suggesting this is something you should do in your Update at all, as this in inefficient, but this is the root cause of your problem
Okay to be basic, I have a 2d top down game on unity. The premises of my game is to collect as much coins as you can before you die. I used player pref so that when a player get the highest score it will save the person's score. However I am facing a problem, which is; when you first play the game, you collect coins then die, the game then saves the highest point you got and displays it on a panel that comes down, BUT if you play the game again and don't collect any coins, then the game doesn't show the highest point you got, instead it will show "0". So to sum up if I don't collect any coins and I die then the panel will come down and show 0 as my high score. So I have to get at least 1 coin for it to show the person highest high score. Which is not want I want, want I want is for when the player dies, regardless of how many coins you have collected, it will show (in my panel) your highest high score the person got to. Does anyone knows how to fix this??? Thank you.
This is my code:
public Text ScoreText;
public Text Highscoretext;
public AudioClip coinsound;
public int Score;
public int highScore = 0;
void Start ()
{
Score = 0;
SetScoreText ();
if (PlayerPrefs.HasKey ("Highscore"))
{
highScore = PlayerPrefs.GetInt("Highscore");
}
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag ("Pick Up"))
{
other.gameObject.SetActive (false);
Score = Score + 1;
SetScoreText ();
AudioSource.PlayClipAtPoint (coinsound, transform.position);
}
}
void SetScoreText ()
{
ScoreText.text = "Score: " + Score.ToString ();
Highscoretext.text = "Highscore" + highScore.ToString ();
}
Thank you.
Just use two playerpref variables. "ScoreThisPlaySesssion" and "HighestScoreEver" count score this session up when you collect coins and when that is higher than "highest score ever" count that up with one value evert time you get a coin.
void Start ()
{
Score = 0;
SetScoreText ();
if (PlayerPrefs.HasKey ("Highscore"))
{
highScore = PlayerPrefs.GetInt("Highscore");
}
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag ("Pick Up"))
{
other.gameObject.SetActive (false);
Score = Score + 1;
SetScoreText ();
AudioSource.PlayClipAtPoint (coinsound, transform.position);
}
}
void SetScoreText ()
{
ScoreText.text = "Score: " + Score.ToString ();
if( PlayerPrefs.GetInt( "highestscoreever", 0 ) < Score )
PlayerPrefs.SetInt( "highestscoreever", Score );
Highscoretext.text = "Highscore" + PlayerPrefs.GetInt( "highestscoreever", 0 );
}