Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

C#: playerprefs not loading or saving

Discussion in 'Scripting' started by DarkBladeNemo, Dec 26, 2016.

  1. DarkBladeNemo

    DarkBladeNemo

    Joined:
    Aug 23, 2013
    Posts:
    116
    Hi everyone

    So I'm having this issue with PlayerPrefs not loading or saving as it seems.
    I have been struggling with this and even looked up some examples but I think my issue might be the way it it set up I dunno. Maybe someone can have a look and tell me what I am doing wrong?

    My script:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class SaveManager : MonoBehaviour {
    6.  
    7.     //Script refference
    8.     public Experience experience;
    9.     public PlayerHealth playerHealth;
    10.     public LevelComplete levelComplete;
    11.     //Bools
    12.     public bool isLevelOneComplete = false;
    13.     public bool DidloadOnce = false;
    14.     //Variable to get S*** working
    15.     public float maxPlayerHealth = 100f;
    16.     public int playerlevel = 1;
    17.     public float expNeeded = 100f;
    18.     public float currentExp = 0f;
    19.     public int levelOneComplete = 0;
    20.  
    21.  
    22.  
    23.     public void SaveGame(){
    24.         Save();
    25.     }
    26.  
    27.     public void LoadGame(){
    28.             Load();
    29.     }
    30.  
    31.  
    32.     void Awake(){
    33.         experience = FindObjectOfType<Experience>();
    34.         playerHealth = FindObjectOfType<PlayerHealth>();
    35.         DontDestroyOnLoad(transform.gameObject);
    36.     }
    37.  
    38.     void Save(){
    39.          PlayerPrefs.SetFloat("MaxHealth", playerHealth.maxHealth);
    40.          PlayerPrefs.SetInt("PlayerLevel", experience.playerLevel);
    41.          PlayerPrefs.SetFloat("ExpNeeded", experience.expNeeded);
    42.          PlayerPrefs.SetFloat("CurrentExp", experience.currentExp);
    43.          if(levelComplete.LevelOneComplete == 1){
    44.             PlayerPrefs.SetInt("LevelOneComplete", levelOneComplete);
    45.          }
    46.          Debug.Log("Saved");
    47.     }
    48.  
    49.     void Load(){
    50.         playerHealth.maxHealth = PlayerPrefs.GetFloat("MaxHealth");
    51.         experience.playerLevel = PlayerPrefs.GetInt("PlayerLevel");
    52.         experience.expNeeded = PlayerPrefs.GetFloat("ExpNeeded");
    53.         experience.currentExp = PlayerPrefs.GetFloat("CurrentExp");
    54.         levelComplete.LevelOneComplete = PlayerPrefs.GetInt("LevelOneComplete");
    55.         Debug.Log("Loaded");
    56.     }
    57. }
    58.  
    The debug goes off so I assume the script completes but nothing happens. Any help would be appreciated and happy holidays everyone :D
     
  2. EdKirby

    EdKirby

    Joined:
    Nov 15, 2013
    Posts:
    43
    I'm still waking up but, I'm not seeing where you are setting any values. For example, you declare and define maxPlayerHealth but you don't assign it to playerHealth.maxHealth. Does playerHealth.maxHealth have a value yet that is being set somewhere else that I'm not aware of? Same goes for the rest of them.

    Otherwise it looks like it should work.
     
  3. DarkBladeNemo

    DarkBladeNemo

    Joined:
    Aug 23, 2013
    Posts:
    116
    bah those you can ignore they were mainly for testing and are not used. These are all the scripts that the save script points to.

    Save script:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class SaveManager : MonoBehaviour {
    6.  
    7.     //Script refference
    8.     public Experience experience;
    9.     public PlayerHealth playerHealth;
    10.     public LevelComplete levelComplete;
    11.     //Bools
    12.     public bool isLevelOneComplete = false;
    13.     public bool DidloadOnce = false;
    14.     //Variable to get S*** working
    15.     //public float maxPlayerHealth = 100f;
    16.     //public int playerlevel = 1;
    17.     //public float expNeeded = 100f;
    18.     //public float currentExp = 0f;
    19.     //public int levelOneComplete = 0;
    20.  
    21.  
    22.  
    23.     public void SaveGame(){
    24.         Save();
    25.     }
    26.  
    27.     public void LoadGame(){
    28.             Load();
    29.     }
    30.  
    31.  
    32.     void Awake(){
    33.         experience = FindObjectOfType<Experience>();
    34.         playerHealth = FindObjectOfType<PlayerHealth>();
    35.         DontDestroyOnLoad(transform.gameObject);
    36.     }
    37.  
    38.     void Save(){
    39.          PlayerPrefs.SetFloat("MaxHealth", playerHealth.maxHealth);
    40.          PlayerPrefs.SetInt("PlayerLevel", experience.playerLevel);
    41.          PlayerPrefs.SetFloat("ExpNeeded", experience.expNeeded);
    42.          PlayerPrefs.SetFloat("CurrentExp", experience.currentExp);
    43.          if(levelComplete.LevelOneComplete == 1){
    44.             PlayerPrefs.SetInt("LevelOneComplete", levelOneComplete);
    45.          }
    46.          Debug.Log("Saved");
    47.     }
    48.  
    49.     void Load(){
    50.         playerHealth.maxHealth = PlayerPrefs.GetFloat("MaxHealth");
    51.         experience.playerLevel = PlayerPrefs.GetInt("PlayerLevel");
    52.         experience.expNeeded = PlayerPrefs.GetFloat("ExpNeeded");
    53.         experience.currentExp = PlayerPrefs.GetFloat("CurrentExp");
    54.         levelComplete.LevelOneComplete = PlayerPrefs.GetInt("LevelOneComplete");
    55.         Debug.Log("Loaded");
    56.     }
    57. }
    58.  
    Experience script:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class Experience : MonoBehaviour {
    7.  
    8.     public int playerLevel = 1;
    9.     public float expLevelModifier = 1.5f;
    10.     public float expNeeded = 100f;
    11.     public float currentExp = 0f;
    12.     /*public Image levelImage;
    13.     public Sprite level1;
    14.     public Sprite level2;
    15.     public Sprite level3;
    16.     public Sprite level4;
    17.     public Sprite level5;
    18.     public Sprite level6;
    19.     public Sprite level7;
    20.     public Sprite level8;
    21.     public Sprite level9;
    22.     public Sprite level10;*/
    23.  
    24.  
    25.  
    26.     // Use this for initialization
    27.     void Start () {
    28.        
    29.     }
    30.  
    31.     public void Awake(){
    32.         DontDestroyOnLoad(transform.gameObject);
    33.     }
    34.    
    35.     // Update is called once per frame
    36.     void Update () {
    37.         if(currentExp >= expNeeded){
    38.             currentExp = 0f;
    39.             Debug.Log("Current EXP set to 0");
    40.             playerLevel += 1;
    41.             Debug.Log("Level Up");
    42.             expNeeded = Mathf.Round(expNeeded * expLevelModifier);
    43.             Debug.Log("EXP Scales");
    44.             //player.maxHealth = Mathf.Round(player.maxHealth * player.healthModifier);
    45.             //Debug.Log("Health Scaled");
    46.         }
    47.  
    48.     /*    if(playerLevel == 1){
    49.             levelImage.sprite = level1;
    50.         }else if(playerLevel == 2){
    51.             levelImage.sprite = level2;
    52.         }else if(playerLevel == 3){
    53.             levelImage.sprite = level3;
    54.         }else if(playerLevel == 4){
    55.             levelImage.sprite = level4;
    56.         }else if(playerLevel == 5){
    57.             levelImage.sprite = level5;
    58.         }else if(playerLevel == 6){
    59.             levelImage.sprite = level6;
    60.         }else if(playerLevel == 7){
    61.             levelImage.sprite = level7;
    62.         }else if(playerLevel == 8){
    63.             levelImage.sprite = level8;
    64.         }else if(playerLevel == 9){
    65.             levelImage.sprite = level9;
    66.         }else if(playerLevel == 10){
    67.             levelImage.sprite = level10;
    68.         }*/
    69.     }
    70. }
    71.  
    The experience gets added from the enemy scripts but that should change a thing. Other than that its only suppose to save the values.

    The playerhealth:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class PlayerHealth : MonoBehaviour {
    7.     //Player Health
    8.     public float currentHealth;
    9.     public float maxHealth = 100f;
    10.     public float healthModifier = 1.5f;
    11.  
    12.  
    13.     public EnemyDamageHandler enemy;
    14.     public Experience experience;
    15.     float curTime = 0;
    16.     float nextDamage = 1;
    17.  
    18.     public AudioClip[] playerHitSound;
    19.  
    20.     void Start(){
    21.         currentHealth = maxHealth;
    22.     }
    23.  
    24.     void Update(){
    25.     if (currentHealth > maxHealth){
    26.         currentHealth = maxHealth;
    27.     }
    28.         if(experience.playerLevel == 1){
    29.             maxHealth = 100f;
    30.         }else if(experience.playerLevel == 2){
    31.             maxHealth = 125f;
    32.         }else if(experience.playerLevel == 3){
    33.             maxHealth = 150f;
    34.         }else if(experience.playerLevel == 4){
    35.             maxHealth = 175f;
    36.         }else if(experience.playerLevel == 5){
    37.             maxHealth = 200f;
    38.         }else if(experience.playerLevel == 6){
    39.             maxHealth = 225f;
    40.         }else if(experience.playerLevel == 7){
    41.             maxHealth = 250f;
    42.         }else if(experience.playerLevel == 8){
    43.             maxHealth = 275f;
    44.         }else if(experience.playerLevel == 9){
    45.             maxHealth = 300f;
    46.         }else if(experience.playerLevel == 10){
    47.             maxHealth = 325f;
    48.         }
    49.        
    50.     }
    51.  
    52.     void Awake(){
    53.         experience = FindObjectOfType<Experience>();
    54.     }
    55.  
    56.     void OnTriggerStay2D(Collider2D other){
    57.         if (other.gameObject.tag == "Enemy" && curTime <= 0) {
    58.             Debug.Log ("Damage");
    59.             AudioSource.PlayClipAtPoint(playerHitSound[Random.Range(0, playerHitSound.Length)], transform.position);
    60.             currentHealth -= enemy.zombieDamage;
    61.             curTime = nextDamage;
    62.         } else {
    63.    
    64.             curTime -= Time.deltaTime;
    65.         }
    66.  
    67.  
    68.        
    69.            
    70.         if(currentHealth <= 0){
    71.             Die();
    72.         }
    73.     }
    74.  
    75.  
    76.     void Die(){
    77.         Destroy(gameObject);
    78.     }
    79. }
    80.  
    Those are the save script and the one it is suppose to save values of. Currently it doesn't seem to be doing anything as it isn't loading so i assume it probably not saving aswell. Note that the save and experience script is set in a preloaded scene and doesn't get destroyed and from there they search for the needed scripts. I don't know if i explained that properly :/ But yeah don't know if that has anything to do with it.
     
  4. EdKirby

    EdKirby

    Joined:
    Nov 15, 2013
    Posts:
    43
    How are you actually triggering the Save?
     
  5. EdKirby

    EdKirby

    Joined:
    Nov 15, 2013
    Posts:
    43
    Disregard....

    I just set up a quick project and I'm getting output:

    MaxHealth100
    UnityEngine.Debug:Log(Object)
    SaveManager:Load() (at Assets/SaveManager.cs:69)
    SaveManager:Start() (at Assets/SaveManager.cs:45)
     
  6. EdKirby

    EdKirby

    Joined:
    Nov 15, 2013
    Posts:
    43
    Had to check something. but yes, it does seem to be reading and writing to PlayerPrefs.
     
  7. DarkBladeNemo

    DarkBladeNemo

    Joined:
    Aug 23, 2013
    Posts:
    116
    The loading and saving are done with UI buttons. I have them on selected buttons. I play the game do a level and then the game is suppose to save. I stop playing and start again but it doesn't load. So it either doesn't load in the editor or im just doing something wrong for it not to work :(

    EDIT: So it is working as expected for you then?
     
  8. EdKirby

    EdKirby

    Joined:
    Nov 15, 2013
    Posts:
    43
    Your save and load code is working for me. So, I don't think it's that.

    To test, what I did was add a void Start() to your SaveManager.cs and called Save() and Load() then output to Debug.Log what was being returned from PlayerPrefs.

    Maybe you can confirm that your save and load code works then once that is verified, go to the next step? Once you know for sure that you can save and load then move to how and when they are being called and go from there.

    You said that you are seeing your debug statements? so the UI buttons are wired ok.
     
  9. EdKirby

    EdKirby

    Joined:
    Nov 15, 2013
    Posts:
    43
    Seems to be. :)
     
  10. DarkBladeNemo

    DarkBladeNemo

    Joined:
    Aug 23, 2013
    Posts:
    116
    Well I fixed it by dragging the exp script from the scene into the save script but now it is giving me an error.

    NullReferenceException: Object reference not set to an instance of an object
    SaveManager.Load () (at Assets/Scripts/SaveManager.cs:51)
     
  11. EdKirby

    EdKirby

    Joined:
    Nov 15, 2013
    Posts:
    43
    Yeah, your Exp script object isn't getting instantiated. So when you call: experience.playerLevel=PlayerPrefs.GetInt("PlayerLevel"); It can't write to an object that isn't there.

    Case in point, when I tested, I added all the scripts to a cube object. So all of them were instantiated when the game started, meaning, you have to have the scripts (or at least one) attached to a GO.

    EDIT: I confirmed that the data was writing to the registry on Windows where the data for PlayerPrefs is stored.
     
    Last edited: Dec 26, 2016
  12. DarkBladeNemo

    DarkBladeNemo

    Joined:
    Aug 23, 2013
    Posts:
    116
    I added the experience script to a empty game object though. Or does it need to be something else? The level of frustration this script is causing me :confused::mad: Seriously though ill add a screenshot.





    and the full long ass error code:

    NullReferenceException: Object reference not set to an instance of an object
    SaveManager.Load () (at Assets/Scripts/SaveManager.cs:51)
    SaveManager.LoadGame () (at Assets/Scripts/SaveManager.cs:28)
    UnityEngine.Events.InvokableCall.Invoke (System.Object[] args) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:153)
    UnityEngine.Events.InvokableCallList.Invoke (System.Object[] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:634)
    UnityEngine.Events.UnityEventBase.Invoke (System.Object[] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:769)
    UnityEngine.Events.UnityEvent.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:53)
    UnityEngine.UI.Button.Press () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:35)
    UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:44)
    UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:52)
    UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:269)
    UnityEngine.EventSystems.EventSystem:Update()


    I know everything should be working and I have gone over everything multiple times but this... this is just annoying. If all else fail mind if I send you the project so you can have a look at the source?
     
  13. EdKirby

    EdKirby

    Joined:
    Nov 15, 2013
    Posts:
    43
    Did you apply the changes to the SaveManager prefab. it shows that you have unapplied changes.

    EDIT: Sure, I'd be happy to take a look if needs be. I'll PM you my email if that time comes. But, what I would say is a little struggle is good but don't get frustrated. Unity is telling you the problem, the Exp object isn't getting instantiated. Once you figure out why it isn't, it'll start working. Or at the very least, that part won't be an issue anymore. ;-)
     
  14. DarkBladeNemo

    DarkBladeNemo

    Joined:
    Aug 23, 2013
    Posts:
    116
    Just checked and apparently PlayerPrefs saves in the registry so i went and had a look but there wasn't anything saved there so I'm thinking for some reason its not working with my Unity version.
     
  15. TaleOf4Gamers

    TaleOf4Gamers

    Joined:
    Nov 15, 2013
    Posts:
    825
    Means it doesnt exists.
    Check these lines (51 and 28)
    What script is it referencing, make sure it exists.