Skip to main content

Save and load from scriptable objects in Unity complete workflow

 




##########################

1. Create a scriptable object class as following and create the scriptable object in Resources folder in project directory

##########################


using System.Collections;

using System.Collections.Generic;

using UnityEngine;


[CreateAssetMenu(fileName = "Data", menuName = "Data/SaveFile", order = 1)]

public class Saves : ScriptableObject

{

    public List<KeyValueData> savedDataList;


}



[System.Serializable]

public struct KeyValueData

{

    public string key;

    public string value;

}



##########################

2. Read and log saved data

For reading create a SaveSystem class as follows

##########################

using System.Collections;

using System.Collections.Generic;

using System.IO;

using System.Runtime.Serialization.Formatters.Binary;

using UnityEngine;


public static class SaveSystem

{

    public static SavedDataSerializer LoadData()

    {

        string path = Application.persistentDataPath + "/SaveFile.asset";


        Debug.Log(path);


        if (File.Exists(path))

        {

            BinaryFormatter formatter = new BinaryFormatter();

            FileStream stream = new FileStream(path, FileMode.Open);

            SavedDataSerializer deSerializedData = (SavedDataSerializer)formatter.Deserialize(stream);

            stream.Close();

            return deSerializedData;

        }

        else

        {

            return null;

        }

    }

}



[System.Serializable]

public class SavedDataSerializer

{

    public List<KeyValueData> serializedData = new List<KeyValueData>();


    public SavedDataSerializer(Saves saveableData)

    {

        serializedData = saveableData.savedDataList;

    }

}



##########################

3. Read data from any class by logging SaveSystem.LoadData();

> currently gives null as the file does not exists in local memory, we can paste the scriptable object asset at the path that is logged from line number 13(46 in this file) in above script

> Upon trying to log the data received error: SerializationException: The input stream is not a valid binary format.

> This suggests that I need to save it in binary format first then only I'll be able to read it.

> In order to directly read the Scriptable Object, I can set the reference to it in a script and read the data from it, as follows:

##########################


public class StatsManager : MonoBehaviour

{


    public Saves savedDataSO;

    // Start is called before the first frame update

    void Start()

    {

        //Debug.Log(SaveSystem.LoadData());



        foreach(KeyValueData keyValueData in savedDataSO.savedDataList)

        {

            Debug.Log("Key: " + keyValueData.key);

            Debug.Log("Value: " + keyValueData.value);


        }




    }


}




##########################

4. Now that we can load a Scriptable Object, let's save it to the location where it is supposed to be in memory

> Add following function to SaveSystem.cs

##########################


public static void SaveData(Saves saveData)

{

    BinaryFormatter formatter = new BinaryFormatter();


    string path = Application.persistentDataPath + "/SaveFile.asset";


    FileStream stream = new FileStream(path, FileMode.Create);


    SavedDataSerializer serializedLevelsData = new SavedDataSerializer(saveData);


    formatter.Serialize(stream, serializedLevelsData);


    stream.Close();



}



##########################

5. Call SaveData after loading the placeholder data from scriptable object in order to save it in binary format

> running the following function should create the file SaveFile.asset in the location(Application.persistentDataPath) that was logged earlier

##########################


public class StatsManager : MonoBehaviour

{

    public Saves savedDataSO;

    // Start is called before the first frame update

    void Start()

    {

        //Debug.Log(SaveSystem.LoadData());


        foreach(KeyValueData keyValueData in savedDataSO.savedDataList)

        {

            Debug.Log("Key: " + keyValueData.key);

            Debug.Log("Value: " + keyValueData.value);


        }



        SaveSystem.SaveData(savedDataSO);

    }


}



##########################

6. Now we should be able to read the saved data

> now if we run the code below it should log the data from the saved location

##########################


public class StatsManager : MonoBehaviour

{


    void Start()

    {


        SavedDataSerializer savedData = SaveSystem.LoadData();


        foreach(KeyValueData keyValueData in savedData.serializedData)

        {

            Debug.Log("Key: " + keyValueData.key);

            Debug.Log("Value: " + keyValueData.value);

        

        }


    }


}



##########################

7. This finishes Scriptable Object based save and load system. Now in order to utilize if properly, we need to setup following few things:

> Check if saved data exists,

if exists

> load saved data

if not

> save referenced scriptable object data to location

> Save data to location when data is updated

Comments

Popular posts from this blog

Unity Mobile Game Optimization Checklist

- On Image and Text components that aren’t interacted with you can uncheck “Raycast Target” on it, as it will remove them from any Raycast calculus. - Click on your textures in your “Project” window. Click on the “Advanced” arrow, and now check “Generate Mip Maps”, Unity especially recommends it for faster texture loading time and a lower rendering time. - Set the “Shadow Cascades” to “No Cascades” (Quality settings) - If you have dynamic UI elements like a Scroll Rect with a lot of elements to visualize, a good practice is to turn off the pixel perfect check box on the canvas that contains the list and disable the items that aren’t visible on the screen. - Set all non moving objects to "Static" - Above Unity3d 2017.2 you should turn off "autoSyncTransforms" on the Physics tab - Always use Crunch Compression Low on textures - Try to keep the “Collision Detection Mode” on “Discrete” if possible, as “Dynamic” demands more performance. - You can go to the TimeManager w...

How to make RPC in Unreal Engine Steam Online Subsystem and EOS

Remote Procedure Calls, also known as RPCs, are a way to call something on any other instance.  In the Unreal Engine, RPCs are used to ship events from the patron to the server, the server to the customer, or from the server to a specific group. It's important to word that RPCs cannot have a return cost. If you want to return something, you'll ought to use a seconds RPC within the contrary path. There are precise policies that RPCs observe, which are unique in the official Documentation. Some of these regulations encompass wherein the RPC must be run, such as the server instance of an Actor, on the owner of the Actor, or on all instances of the Actor. There are some necessities for RPCs. First, they must be referred to as on Actors or replicated Subobjects. The Actor (and component) have to additionally be replicated. If the server is looking an RPC to be executed on a customer, handiest the patron who owns that Actor will execute the function. Similarly, if a client is calling...

How to drag and drop item in Unity3D

  For dragging and dropping to work we will need to first grab the Game Object and ensure while the Game Object remains grabbed it's position reciprocates the mouse position. This will work fine for not only PC bug mobile devices as well. First define GameObject which we will be dragging. public GameObject selectedPiece; Now inside Update method we will give reference to touched/clicked object and while there is a reference available to an game object(selectedPiece;) we will move that object to mouse position. When the reference is remove, object won't move therefore dropped. void Update(){ RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero); if (Input.GetMouseButtonDown(0)){ if(hit.transform != null)             {                 if (hit.transform.CompareTag("PIECE"))                 {     ...