Save Load System

Hey everybody. I need help making a save load system for my game. What I need to get saved is the player’s location and inventory, and everything the player interacted with and changed.

Well, first critical part is gathering up all that information into a single place. The actual gathering of that information is VERY game dependent… you need to decide what things to save, and write some function that gathers all the data.

Next we need to serialize that data. Easy option is to create a class that is serializable that you can set all those collected values into (just have fields for everything you need to save).

Now you can serialize that class up into something like say XML, or binary data, or whatever. Look here for how to serialize using the .net/mono serialization library:

(note, this will NOT support serializing GameObjects and unity specific stuff directly… this is why Unity has its custom serialization system)

Lastly you need somewhere to store that data. Usually you can store it to disk, or to a server, or anything like that.

Other “easier” (ish… I personally don’t like some of these) include PlayerPrefs, which basically just writes entries into the Registry (hence why I don’t like it). When you gather up that information, you write it into the PlayerPrefs.

Reasons I don’t like that option:

  1. It writes to the registry… UGH. Don’t clutter up the registry like that.
  2. Having multiple save files becomes convoluted. Where as if you save to disk, you can just change/increment the filename to have multiple save files.
  3. The save information is stuck in the registry, you can’t easily move that around. Where as a save file can be copy/pasted/deleted very easily.

http://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/persistence-data-saving-loading

using System;
using FullSerializer;

public static class StringSerializationAPI {
    private static readonly fsSerializer _serializer = new fsSerializer();

    public static string Serialize(Type type, object value) {
        // serialize the data
        fsData data;
        _serializer.TrySerialize(type, value, out data).AssertSuccessWithoutWarnings();

        // emit the data via JSON
        return fsJsonPrinter.CompressedJson(data);
    }

    public static object Deserialize(Type type, string serializedState) {
        // step 1: parse the JSON data
        fsData data = fsJsonParser.Parse(serializedState);

        // step 2: deserialize the data
        object deserialized = null;
        _serializer.TryDeserialize(data, type, ref deserialized).AssertSuccessWithoutWarnings();

        return deserialized;
    }
}

What exactly do you need help with?

I tried using the Persistance Saving and Loading Data from the Unity Site that rakkarage linked. I got to the end, but it comes up with these three errors.

Assets/Scripts/GameControl.cs(51,5): error CS1525: Unexpected symbol class' Assets/Scripts/GameControl.cs(53,14): error CS1525: Unexpected symbol public’
Assets/Scripts/GameControl.cs(54,1): error CS1519: Unexpected symbol `end-of-file’ in class, struct, or interface member declaration

Here’s what I have for my script:

using UnityEngine;
using System.Collections;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

public class GameControl : MonoBehaviour {

    public static GameControl control;

    public float health;
    public float key;

    // Use this for initialization
    void Awake () {
        if (control == null) {
            DontDestroyOnLoad (gameObject);
            control = this;
        }
        else if(control != this)
        {
            Destroy(gameObject);
        }
    }

    public void Save() {
        BinaryFormatter bf = new BinaryFormatter ();
        FileStream file = File.Create (Application.persistentDataPath + "save.dat");
       
        SaveData data = new SaveData();
        data.health = health;
        data.key = key;

        bf.Serialize(file, data);
        file.Close ();
    }
    public void Load()
    {
        if(File.Exists (Application.persistentDataPath + "save.dat"))
            {
                BinaryFormatter bf = new BinaryFormatter();
                FileStream file = File.Open (Application.persistentDataPath + "save.dat", FileMode.Open);
                SaveData data = (SaveData)bf.Deserialize (file);
                file.Close ();

                health = data.health;
                key = data.key;
}

(Serializable)                        
class SaveData{
    public float health;
    public float key;
}

Try wrapping Serializable in brackets and see what happens :wink:

I did that and it gave these errors.

Assets/Scripts/GameControl.cs(50,2): error CS1525: Unexpected symbol [' Assets/Scripts/GameControl.cs(53,14): error CS1525: Unexpected symbol public’
Assets/Scripts/GameControl.cs(39,17): warning CS0642: Possible mistaken empty statement
Assets/Scripts/GameControl.cs(54,1): error CS1519: Unexpected symbol `end-of-file’ in class, struct, or interface member declaration

also missing two } at end of load

Thanks for the help guys, I got it working now.

Why aren’t you using PlayerPrefs saving?

…Really?
http://forum.unity3d.com/threads/save-load-system.317734/#post-2061976

I didn’t see it sorry -_- but what is the best way to save a game for windows/linux without using the above things? I thought Playerprefs is the best option available

I’m not expert on the subject, but I’d suggest data serialization as rakkarage presented.
Check out the first link in his first post, and go to around 27:00 in the video.
Player prefs are plain text (I think), so they could be easily found and edited. Serialized data is converted to binary so it’s more secure in a sense.

1 Like