Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by piercepierson · Jan 20, 2020 at 08:13 PM · scoresave datastatescoreboard

How do you save scores and update a scoreboard with them?

Hi,

I'm pretty new to coding in general and am trying to have a table that takes the most recent score received in a game and adds it. I thought that a good way to do it would be to add the score at the Game Over scene because that displays the current score, but it hasn't been destroyed yet. Then, the score in that table would be preserved into the start scene.

The end goal is to have a list of preserved scores, so those can be referenced by other programs.

My two issues are that 1) The table is disappearing in the Game Over scene (Scene 11, yes I know it's bad practice to reference a number, but I just wanted to get it working first before I clean up. If you have a better solution for how to accomplish what I'm going for, please let me know.). And 2) I can't add the currentScore (at the time the game ends, that would be the final score, but not sure of a better way to do it then calling currentScore at the end of the game) to the table.

Below are the two main scripts that I have (one of which is mainly edited from a tutorial). One controls some game features and has the currentScore variable. The other one controls the table and references the other script's score variable (unsuccessfully).

See line 77 of GameScoreTable, which is commented out right now to avoid errors, but that is attempting to add the currentScore to the table.

Thanks!

GameSession:

 using System.Collections;
 using System.Collections.Generic;
 using System;
 using UnityEngine;
 using UnityEngine.UI; // need for text component
 using TMPro;
 using UnityEngine.SceneManagement;
 
 public class GameSession : MonoBehaviour
 {
     // config params
     [Range(0.1f, 10f)] [SerializeField] float gameSpeed = 1f;
     [SerializeField] int pointsPerBlockDestroyed = 83;
     [SerializeField] TextMeshProUGUI scoreText;
     [SerializeField] TextMeshProUGUI savedScoreText;
     [SerializeField] bool isAutoPlayEnabled;
 
     // state variables
     [SerializeField] public int currentScore = 0; // made public to be accessed in other scripts
     [SerializeField] int savedScore; // should I set this to 0 or not? No. it's good now
     Text text; // using for the highscore/savedScore state variable
 
     private void Awake()
     {
         int gameStatusCount = FindObjectsOfType<GameSession>().Length;
         if (gameStatusCount > 1)
         {
             gameObject.SetActive(false);
             Destroy(gameObject);
         }
         else
         {
             DontDestroyOnLoad(gameObject);
         }
     }
 
     private void Start()
     {
         scoreText.text = currentScore.ToString();
         // This loads data from GlobalControl but I'm commenting it out
         // currentScore = GlobalControl.Instance.currentScore;
 
         // below is for highscore scripting
         text = GetComponent<Text>(); // do I need this?  ______________________________
         savedScore = PlayerPrefs.GetInt("saved score", savedScore);
         // Commented out the following because the below made it redundant: text.text = savedScore.ToString();
         // This gets the highscore to display
         savedScoreText.text = savedScore.ToString(); // This may be redundant given the above text. Now just need to apply that to a text object in the game
     }
 
     // Update is called once per frame
     void Update()
     {
         Time.timeScale = gameSpeed;
         // Below is for saving state like score and this is used for highscore but I turned highscore to Saved Score
         if(currentScore > savedScore)
         {
             savedScore = currentScore;
             text.text = "" + currentScore; 
 
             PlayerPrefs.SetInt("saved score", savedScore);
         }
 
         /* Commenting out the below since it's happening in another script: GameScoreTable
         if (SceneManager.GetActiveScene().ToString() == 11.ToString()) // convert both to string to make a bool, stupid solution, but should work since GameOver is 11
             //This is trying to have it so if the scene is gameover, currentscore gets added to the list in gamescoretable
         {
             gameObject.GetComponent<GameScoreTable.GameScoreEntry>().score = currentScore; // want to populate "score" within GameScoreEntry as the currentScore
         }
         */
 
     }
 
     public void AddToScore()
     {
         currentScore += pointsPerBlockDestroyed;
         scoreText.text = currentScore.ToString();
     }
 
     public void ResetGame()
     {
         Destroy(gameObject);
     }
 
     public bool IsAutoPlayEnabled()
     {
         return isAutoPlayEnabled;
     }
 
     // This is from highscore script, took out private so now maybe it will work
     public void OnDestroy()
     {
         PlayerPrefs.SetInt("saved score", savedScore);
         PlayerPrefs.Save();
     }
 
     // Adding below method to call in GameScoreTable
     public int CallSavedScore()
     {
         return savedScore;
     }
 
 }

   

GameScoreTable:

 /* 
     ------------------- Code Monkey -------------------
 
     Thank you for downloading this package
     I hope you find it useful in your projects
     If you have any questions let me know
     Cheers!
 
                unitycodemonkey.com
     --------------------------------------------------
     https://unitycodemonkey.com/video.php?v=iAbaqGYdnyI
  */
 
 using System.Collections;
 using System.Collections.Generic;
 using System;
 using UnityEngine;
 using UnityEngine.UI;
 using TMPro;
 using UnityEngine.SceneManagement;
 
 // commented out the following because don't have CodeMonkey namespace: using CodeMonkey.Utils;
 
 public class GameScoreTable : MonoBehaviour {
 
     // I want instad of the name, I sort by game number and instead of sorting by score highest to lowest, I sort by name which is the game number. Figure out.
 
     private Transform entryContainer;
     private Transform entryTemplate;
     // There used to be this so may want to put in my version if necessary: private List<HighscoreEntry> highscoreEntryList;
     public List<GameScoreEntry> gameScoreEntryList; // edited from the above, made public to match below
     public List<Transform> gameScoreEntryTransformList; // changed from highscoreEntryTransformList, also made public
 
     // Adding this to link to my main state script
     // GameSession.savedScore is the highscore? below commented out so no errors and also did the same in Awake beginning
     GameSession gameSession;
     int savedScore;
 
     private void Awake()
     {
         gameSession = FindObjectOfType<GameSession>(); // for looking up scores
         savedScore = gameSession.CallSavedScore(); // for returning savedScore from GameSession
 
         entryContainer = transform.Find("gameScoreEntryContainer"); // used to be highscoreEntryContainer so may need to change associations elsewhere
 
         entryTemplate = entryContainer.Find("gameScoreEntryTemplate"); // used to be highscoreEntryTemplate so may need to change associations elsewhere, this is null ref
         // It may be acceptable because it's going to false after running the default so I'll leave it for now and come back later
 
         entryTemplate.gameObject.SetActive(false); // hides the default template
 
         // clear default scores before json tracks
         clearScoreTable();
 
         string jsonString = PlayerPrefs.GetString("gameScoreTable");
         GameScores gameScores = JsonUtility.FromJson<GameScores>(jsonString); // JsonUtility stores a list of scores and converts an object to json
 
         if (gameScores == null) // This was after line 34 but just deleted at 14 mins; It may be not working because need the names to initialize
         {
             // There's no stored table, initialize
             Debug.Log("Initializing table with default values...");
             AddGameScoreEntry(1000000, "CMK");
             AddGameScoreEntry(897621, "JOE");
             AddGameScoreEntry(872931, "DAV");
             AddGameScoreEntry(785123, "CAT");
             AddGameScoreEntry(542024, "MAX");
             AddGameScoreEntry(68245, "AAA");
             // Reload
             jsonString = PlayerPrefs.GetString("gameScoreTable");
             gameScores = JsonUtility.FromJson<GameScores>(jsonString);
         }
 
         if (SceneManager.GetActiveScene().ToString() == 11.ToString()) // below had errors so commented out, but I want to put stuff here. try with each of the two below
         {
             DontDestroyOnLoad(gameObject); // adding so it isn't destroyed on load because it's disappearing in game over
             AddGameScoreEntry(gameObject.GetComponent<GameSession>().currentScore, "ACE"); // used to be the following bu took out 1 because no name assigned: AddGameScoreEntry(gameObject.GetComponent<GameSession>().currentScore, 1)
             gameObject.GetComponent<GameScoreEntry>().score = gameObject.GetComponent<GameSession>().currentScore; // want to populate "score" within GameScoreEntry as the currentScore, drawing from gamesession
             gameObject.GetComponent<GameScoreEntry>().score = GameObject.FindObjectOfType<GameSession>().currentScore; // same as above
         }
 
         // Sort entry list by Score
         for (int i = 0; i < gameScores.gameScoreEntryList.Count; i++)
         { // This goes through the entire list
             for (int j = i + 1; j < gameScores.gameScoreEntryList.Count; j++) // For all elements, cycle through the ones after j
             { 
                 if (gameScores.gameScoreEntryList[j].score > gameScores.gameScoreEntryList[i].score) // Test to see which element has the highest score
                 { 
                     // Swap positions if needed
                     GameScoreEntry tmp = gameScores.gameScoreEntryList[i];
                     gameScores.gameScoreEntryList[i] = gameScores.gameScoreEntryList[j];
                     gameScores.gameScoreEntryList[j] = tmp;
                 }
             }
         }
 
         gameScoreEntryTransformList = new List<Transform>();
         foreach (GameScoreEntry gameScoreEntry in gameScores.gameScoreEntryList)
         {
             CreateGameScoreEntryTransform(gameScoreEntry, entryContainer, gameScoreEntryTransformList);
         }
     }
 
     // changed below from create highscoreentryTransform and highscoreEntry; may need to change others to gameScoreEntry; instantiated transform goes from this list
     private void CreateGameScoreEntryTransform(GameScoreEntry gameScoreEntry, Transform container, List<Transform> transformList)
     {
         float templateHeight = 31f;
         Transform entryTransform = Instantiate(entryTemplate, container); // instantiate entry transform based on template
         RectTransform entryRectTransform = entryTransform.GetComponent<RectTransform>();
         entryRectTransform.anchoredPosition = new Vector2(0, -templateHeight * transformList.Count); // position based on the template height
         entryTransform.gameObject.SetActive(true); // now true to display the list
 
         // This is the switch for ranking but could probably use this to display the most recent games
         int rank = transformList.Count + 1;
         string rankString;
         switch (rank) {
         default:
             rankString = rank + "TH"; break; // This is 4th-10th, not necessary for other rankings
 
         case 1: rankString = "1ST"; break;
         case 2: rankString = "2ND"; break;
         case 3: rankString = "3RD"; break;
         }
 
         // This updates text field and it used to be:         entryTransform.Find("posText").GetComponent<Text>().text = rankString;
         entryTransform.Find("gameNumText").GetComponent<Text>().text = rankString; // Still want to rank because want it to sort by most recent first
 
         int score = gameScoreEntry.score;
 
         entryTransform.Find("scoreText").GetComponent<Text>().text = score.ToString();
 
         // maybe don't need if I don't have a name so commenting out; or maybe this should be catalogued like gameScoreEntry.game
         string name = gameScoreEntry.name;
         entryTransform.Find("nameText").GetComponent<Text>().text = name;
 
         // Set background visible odds and evens, easier to read
         entryTransform.Find("background").gameObject.SetActive(rank % 2 == 1);
         
         // Highlight most recent game score
         if (rank == 1) {
             entryTransform.Find("gameNumText").GetComponent<Text>().color = Color.green; // changed association
             entryTransform.Find("scoreText").GetComponent<Text>().color = Color.green;
             entryTransform.Find("nameText").GetComponent<Text>().color = Color.green;
         }
 
         // Set tropy
         /* The below uses the UtilsClass which was in a Namespace I don't have, so I took it out, but could use to rank in the future
          * Default hides trophy image and and the others make it a different color depending on rank
         switch (rank) 
         {
         default:
             entryTransform.Find("trophy").gameObject.SetActive(false);
             break;
         case 1:
             entryTransform.Find("trophy").GetComponent<Image>().color = UtilsClass.GetColorFromString("FFD200");
             break;
         case 2:
             entryTransform.Find("trophy").GetComponent<Image>().color = UtilsClass.GetColorFromString("C6C6C6");
             break;
         case 3:
             entryTransform.Find("trophy").GetComponent<Image>().color = UtilsClass.GetColorFromString("B76F56");
             break;
         }
         */
         transformList.Add(entryTransform);
     }
 
     private void AddGameScoreEntry(int score, string name) // used to be AddHighScoreEntry
     {
         // Create GameScoreEntry
         GameScoreEntry gameScoreEntry = new GameScoreEntry { score = score, name = name }; // may need to change based on associations
         
         // Load saved Highscores, adds to saved list by using playerprefs
         string jsonString = PlayerPrefs.GetString("gameScoreTable"); // change highscoreTable later
         GameScores gameScores = JsonUtility.FromJson<GameScores>(jsonString);
 
         if (gameScores == null) // gameScores was highscores, so may needed to change elsewhere
         {
             // There's no stored table, initialize
             // I think I could add scores here
             gameScores = new GameScores()
             {
                 gameScoreEntryList = new List<GameScoreEntry>()
             };
         }
 
         // Add new entry to Highscores
         gameScores.gameScoreEntryList.Add(gameScoreEntry);
 
         // Save updated Highscores
         string json = JsonUtility.ToJson(gameScores); // video called highscores as highscoreEntryList, but needs to be an object that contains a list instead of the list itself so changed to gameScores
         PlayerPrefs.SetString("gameScoreTable", json); // stores all data
         PlayerPrefs.Save();
     }
 
     // clears default table scores so that it can be tracked in the game, then this is called in Awake
     private void clearScoreTable()
     {
         // Load saved scores
         string jsonString = PlayerPrefs.GetString("gameScoreTable");
         GameScores gameScores = JsonUtility.FromJson<GameScores>(jsonString); 
 
         //Clear scores table
         gameScores.gameScoreEntryList.Clear();
 
         //Save updated scores
         string json = JsonUtility.ToJson(gameScores);
         PlayerPrefs.SetString("scoreTable", json);
         PlayerPrefs.Save();
     }
 
     [System.Serializable]
     public class GameScores // Used to be Highscores and private here, but made public because needs to be in unity 2019 and added serializable above to affect this
     {
         public List<GameScoreEntry> gameScoreEntryList;
     }
 
     /*
      * Represents a single Game score entry; used to be a high score entry
      * */
     [System.Serializable] // makes the bellow serializable
     // This is where I may need to add the reference to other highscores
 
     public class GameScoreEntry // Used to be private here, but made public because needs to be in unity 2019
     {
 
         /*This wasn't working so commented out
         GameSession gameSession;
         int savedScore;
         gameSession = GameObject.FindObjectOfType<GameSession>().currentScore; // for looking up scores
         savedScore = gameSession.CallSavedScore(); // for returning savedScore from GameSession
         
         GameSession gameSession = FindObjectOfType<GameSession>();
         */
 
         public int score = GameObject.FindObjectOfType<GameSession>().currentScore; // I want to reference GameSession savedScore. Here was: public int score but want to access the awake part;a
         
         public string name; // this might be inidividual games?
     }
 
 }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

195 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

show score and keep score on screen until start new game? 0 Answers

Get user score in Game Center Scoreboard 0 Answers

Highscore system unity C# 0 Answers

How to add and track scoring in online multiplayer with UI? (Unet) 0 Answers

reload game 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges