# Save/Load Manager

### Adding New Saveables

1. Implement the **ISaveable** interface to your script, then you will need to define the interface methods in your script.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2F2usC5T67apSoDmjAREMK%2FScreenshot_3.png?alt=media&#x26;token=fc118b81-3ed2-4e11-be12-3d2615d5bccd" alt=""><figcaption></figcaption></figure>

2. Specify what should be saved in the **OnSave()** method and what should be loaded in the **OnLoad()** method.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2FF4T2tJWPhpPa5wIShbxa%2FScreenshot_4.png?alt=media&#x26;token=23ad2528-1492-48d3-9611-bd1e3501cb1b" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
The **StorableCollection** is essentially a **Dictionary** that uses a string as the key and an object as the value. The object can also be a new **StorableCollection** that contains additional values.
{% endhint %}

Here are the data types that can be serialized by **Newtonsoft.Json** in Unity:

* All primitive types, such as int, float, double, bool, and string.
* Arrays and lists of primitive types.
* Custom classes that have public properties or fields, as long as they do not contain circular references.
* Dictionaries that have string keys and values of primitive types or custom classes that meet the above criteria.

3. Go to **GAMEMANAGER -> Save Game Manager** and select the **Find Saveables** button. This will automatically locate all components in the scene that have implemented the **ISaveable** interface.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2FcfXgwx5Wh1IJypiZ2xJv%2Fsave_game.png?alt=media&#x26;token=3a6edc19-e1b4-4499-9879-bfacbf7c8b04" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
**Don't forget to&#x20;**<mark style="color:red;">**SAVE**</mark>**&#x20;your scene after locating all saveables.**

This is necessary because finding saveables creates a new GUID for each component, which is used to serialize the data. When you load the game, the GUID is used to locate a reference to a specific component. If you don't save the scene, it won't be able to locate the correct GUID reference.
{% endhint %}

{% hint style="warning" %}
If a referenced saveable is removed from the scene, its GUID will still be stored in the saveables list. It's a good to use the **Find Saveables** button again to recreate the saveables list and avoid any issues during the serialization process.
{% endhint %}

4. You can open the **Saveables Explorer** by clicking the package button in the right corner of the Saveables Searcher. Within the **Saveables Explorer**, you can check if all the required saveables are located.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2FITRX8fcjb1aGBF0N8pBS%2Fopen_save_explorer.png?alt=media&#x26;token=efc75e36-a1a8-4c75-9270-0e9ef58e9bf2" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2Fj3iYKCQXtKJKiMuixrf1%2Fsave_explorer.png?alt=media&#x26;token=0a0893f6-db2e-45d6-8cd7-6e32967cf7b2" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
By using the **InspectorHeader** attribute in your script, you can change the header of the script to the same fancy header used in almost all scripts in the UHFPS. This header also indicates which scripts are saveable, making it easier to keep track of them without opening the script editor.
{% endhint %}

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2FQsJZvE19FN19QC8IFp2B%2FScreenshot_7.png?alt=media&#x26;token=f37013a0-3a9b-47e5-ae51-51d1efde751b" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2Fw21eJFFrFjagah7P0fPS%2FScreenshot_6.png?alt=media&#x26;token=57d0a2dd-c95d-4e56-a9ba-2fd1bf96b0cb" alt=""><figcaption></figcaption></figure>

### Adding Runtime Saveables

1. Change the script to inherit from **SaveableBehaviour**. The **SaveableBehaviour** class creates a **UniqueID** that is used with **SaveGameManager** to identify which data belongs to which component within the object.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2FNMRuckvbsHlqUH24K0Le%2FScreenshot_9.png?alt=media&#x26;token=0d2d58bf-9c1e-4672-a9fe-74343952987b" alt=""><figcaption></figcaption></figure>

2. Override the **OnSave()** and **OnLoad()** methods and specify which data you want to save or load in the same way as you would when using the ISaveable interface.
3. Open the **Object References** asset, which can be found in the **Save Game Manager** component.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2FRrUEwxTqFy5zLH1M0LGN%2FScreenshot_1.png?alt=media&#x26;token=f6fa2301-34cd-4200-ab65-c3b2048bee02" alt=""><figcaption></figcaption></figure>

3. Add your **Prefab**, which contains a script that inherits from **SaveableBehaviour**, to the Object References list by dragging the Prefab or Folder containing the Prefabs to the window.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2FHhZ2kTHT0TOVaeQF20e2%2FScreenshot_2.png?alt=media&#x26;token=01771a6e-4022-40af-8129-9ee01216b755" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Adding a Prefab to the Object References will create a GUID that is used with the Save Game Manager to instantiate the object when the game is loaded at runtime.
{% endhint %}

{% hint style="info" %}
The **Interactable Item** component already inherits from **SaveableBehaviour**, so when you drop the item from the inventory, it will be automatically added to the runtime saveables.
{% endhint %}

4. To instantiate a saveable object at runtime, you must use the **SaveGameManager.InstantiateSaveable** method. When using this method, the manager will automatically locate the saveables within the object and add them to the runtime saveables.

```csharp
using UnityEngine;
using UHFPS.Runtime;

public class RuntimeSaveableTest : MonoBehaviour
{
    public ObjectReference ObjectReference;

    private void Start()
    {
        GameObject obj = SaveGameManager.InstantiateSaveable(ObjectReference, Vector3.zero, Vector3.zero);
        // do something with instantiated game object
    }
}
```

* To specify which object reference to instantiate, use the **ObjectReference** field. This field is similar to a GameObject field, but instead of providing a direct reference to the GameObject, you provide the GUID to the object reference.

<figure><img src="https://2665493337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh8bp6Jx5qkS4c0NEaWR1%2Fuploads%2FYD0bwVm5aepRQmZ3tq3Y%2FScreenshot_3.png?alt=media&#x26;token=2bbe3495-00be-4198-a016-1b59cdeb4a77" alt=""><figcaption></figcaption></figure>
