Saving data in Unity

Question

The game is an open world game where you can walk and drive around with different vehicles and place structures on the ground. Because the world is huge I want player and different vehicles/structures to stay where they were left. For this reason I need to somehow store positions, rotations, timestamps, materials etc. First I thought of PlayerPrefs but what I've read it's not that safe. So I started doing my own binary file and this is what I've got so far:

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

public class SaveLoad : MonoBehaviour {

    public static void SavePlayer(){
        BinaryFormatter bf = new BinaryFormatter ();
        FileStream stream = new FileStream (Application.persistentDataPath + "ftv.gha", FileMode.Create);

        PlayerData data = new PlayerData ();

        bf.Serialize (stream, data);
        stream.Close ();
    }

    public static float[] LoadPlayer(){
        if (File.Exists (Application.persistentDataPath + "ftv.gha")) {
            BinaryFormatter bf = new BinaryFormatter ();
            FileStream stream = new FileStream (Application.persistentDataPath + "ftv.gha", FileMode.Open);

            PlayerData data = bf.Deserialize (stream) as PlayerData;
            stream.Close ();

            return data.position;
        } else {
            Debug.LogError ("File does not exist.");
            return new float[]{0,0,0};
        }
    }

}

[Serializable]
public class PlayerData
{
    public float[] position;

    public PlayerData(){
        position = new float[3];
        position[0] = GameObject.Find ("Astronaut").transform.position.x;
        position[1] = GameObject.Find ("Astronaut").transform.position.y;
        position[2] = GameObject.Find ("Astronaut").transform.position.z;
    }
}

With this script I'm able to save and load data of one gameobject ONLY (player). The problem is that I have 6-7 vehicles that I also need to save. Also player can place 20-30 drills around the world and I need to save data from those also. I'm not even going to start with other not so important things.

Copy pasting this code for each object sounds like a horrible idea but after watching tens of videos on YouTube (and testing them for literally over 20 hours) I have not found any answers. I've found two kind of videos:

  1. Explains how to save level, health, strength OF ONE OBJECT
  2. Explains how to save position OF ONE OBJECT

So. Is there better way to achieve what I'm trying to explain or am I doing something wrong?

Somebody please point me in the right direction so I can finally start to scale things up.


Show source
| c#   | save   | unity3d   | binaryfiles   2017-01-03 23:01 1 Answers

Answers ( 1 )

  1. 2017-01-04 00:01

    Good job using serialization. Here's what I would do:

    1. Create an interface called ISaveable with one method called save (or two methods save and load).
    2. Implement the interface for each different object that needs it's own specific serializable object and save logic.
    3. Add the implementation scripts to objects in the scene.
    4. In your save method of SaveLoad gameobject, use FindObjectsOfType(Saveable) Unity Documentation
    5. Iterate over the objects returned and call their save methods.

    See the strategy pattern for implementing the ISaveable interface.

◀ Go back