Search Unity

Question Saving and loading and instantiating the player

Discussion in 'Scripting' started by liquidsht, Sep 4, 2020.

  1. liquidsht

    liquidsht

    Joined:
    Jun 4, 2020
    Posts:
    49
    Hi I am making a metroidvania game but ran into some issues with save and load.
    I assume I would instantiate the player each time game is loaded from a saved game. So how would I go about loading the player's health and instantiating. Would I go something like:
    //instantiate player
    //load players health =100
    //set players health =100? where should I place this script that sets the players Health? a singleton GameManager?

    I am not sure how its normally done, so any help to start me off would be great. I am also using the asset EasySave, any advice specifc to EasySave would be even more helpful. TIA.
     
  2. Capricornum

    Capricornum

    Joined:
    Feb 1, 2018
    Posts:
    22
    There are a few ways to save and load in Unity.
    For something as simple as a few ints or strings or floats you can use the PlayerPrefs. These are values stored within Unity and remembered even after quiting the game.
    You can use something like:
    PlayerPrefs.SetInt("PlayerHealth", 100);
    PlayerPrefs.GetInt("PlayerHealth");
     
  3. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    I cant tell you anything about EasySave. However to persist values between game sessions you need to write them to the drive in one way or another. For little things like these, Unity offers its PlayerPrefs. https://docs.unity3d.com/ScriptReference/PlayerPrefs.html
    PlayerPrefs has a couple functions for Setting and Getting values. When quitting the game or changing the scene, you would save values such as player health to PlayerPrefs. When loading a new scene or starting the game, you would get the saved values there.

    As a specific example, even tho the documentation already gives some, you could save your playerHealth OnDestroy()
    Code (CSharp):
    1. PlayerPrefs.SetInt("playerHealth", playerHealth);
    and then load it in Start()
    Code (CSharp):
    1. playerHealth = PlayerPrefs.GetInt("playerHealth", maxHealth); // the second is the default value if it cannot find the entry
    @Capricornum was a second faster :p
     
    Capricornum likes this.
  4. liquidsht

    liquidsht

    Joined:
    Jun 4, 2020
    Posts:
    49
    Sorry, I probably should have been more specific.
    My game will probably end up having an inventory system and among other things, so player prefs probably will not be enough.
    So I am probably going to have to go with saving to a file. I have gotten EasySave to work with health and player location but I am not sure how to do it if I have to instantiate a character.
     
  5. adehm

    adehm

    Joined:
    May 3, 2017
    Posts:
    369
    I don't know anything about EasySave which may make things easier for you but PlayerPrefs can be used for all your saving needs.

    Typically when saving you would save everything as one long string of data that you assign when you load your program. Rather then try to explain this to you I found a simple explanation here that relates https://kbroman.org/dataorg/pages/csv_files.html
     
  6. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    I've used EasySave a good bit in the past. From what I remember, it's a bit tricky setting up serialization for your custom classes (like you'll want to do here), but once you get it going, it couldn't be easier.

    I would make a class for everything you need to save/load about the player. This would be things like currentHealth, position, rotation, inventoryItems, etc. Then add that class to EasySave's list of serializable classes. When your save function runs, populate the fields you need in your class from the player, then serialize and save that data to file.

    When you load the game, you want to initialize your scene like you would otherwise, but then call your load function to apply those saved properties to your player (and elsewhere, of course, any other modified objects) before giving control to the player.

    Whether you do that in a singleton game manager or some other means is a design decision that can be hotly debated until the cows come home. I like singleton managers, but I recognize they have issues, too. Really, whatever lets you move forward and keep making progress is the right pattern for you, so just do what makes sense for you.
     
  7. liquidsht

    liquidsht

    Joined:
    Jun 4, 2020
    Posts:
    49
    Thanks guys, I seem to have some success with EasySave, at least with player stats and position. Now I just have to look into how to save inventory.
     
  8. Capricornum

    Capricornum

    Joined:
    Feb 1, 2018
    Posts:
    22
    I successfully used the binary formatter provided by unity to save and load some stuff.
    Here is a discussion about it. Link.
    It's a little tricky as it can only serialize certain kinds of data like floats, ints, Vector3's I think, but I am not sure. So you might have to do some manual translation from your classes so some serializable stuff.