Page 1 of 1

[HOWTO] How To: Include Summary Info In Saved Games

Posted: Mon Sep 23, 2019 10:43 am
by Tony Li
Someone asked how to include summary info in saved games.

There are generally two approaches. The first is to maintain a separate file (or files) containing summary information about each saved game. The second is to put each saved game's summary info in the saved game itself. In this post, I'll describe how to do the second approach.

Write a new Saver script to hold the summary info. It might look something like below. (I'm going to abbreviate it a bit.)

Code: Select all

public class GameSummarySaver : Saver
{
    [Serializable]
    public class Data
    {
        public string sceneName;
        public string totalPlayTime;
        public int characterLevel;
    }

    public override string RecordData()
    {
        var data = new Data();
        data.sceneName = SceneManager.GetActiveScene().name;
        // ... etc. for everything in Data ...
        return SaveSystem.Serialize(data);
    }

    public override void ApplyData(string s)
    {
        // Do nothing. We only record the data for the save/load menu.
        // There's no need to re-apply it when loading a saved game.
    }
}
Add this script to the Dialogue Manager, and give it a unique key such as "GameSummary". Now, when you save a game, it will save sceneName, totalPlayTime, etc., under the key "GameSummary".

If you need to save image data such as a screenshot of the current gameplay screen, add a byte[] array to Data. Use ImageConversion.EncodeToJPG (or PNG, etc.) to convert the screenshot to the byte[] array. To turn it back into an image, use ImageConversion.LoadImage. If you need to save a player character portrait, you may find it easier to save the name or index of the portrait and look up the image by this name or index instead of serializing the entire image.

When showing your load game menu, call SaveSystem.HasSavedGameInSlot(#).

If it's false, show the slot as "No Save".

If it's true, then call SaveSystem.storer.RetrieveSavedGameData(#). This will return a SavedGameData object. Get the game summary:

Code: Select all

var savedGameData = SaveSystem.storer.RetrieveSavedGameData(#);
var s = savedGameData.GetData("GameSummary");
var summary = SaveSystem.Deserialize<GameSummarySaver.Data>(s);
Then you can show summary.sceneName, summary.totalPlayTime, etc., in your load game menu.

---

Added - How To Save Screenshot:

Code: Select all

public byte[] GetScreenshotBytes()
{
    var screenshotTexture = TakeScreenshot();
    return ImageConversion.EncodeToJPG(screenshotTexture);
}

public Texture2D TakeScreenshot()
{
    var screenshotTexture = new Texture2D(Screen.width, Screen.height);
    screenshotTexture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
    screenshotTexture.Apply ();
    return screenshotTexture;
}
Use ImageConversion.LoadImage() to convert the byte[] array back to a texture.

Re: How To: Include Summary Info In Saved Games

Posted: Wed Dec 09, 2020 3:48 pm
by Jamez0r
Worked great, thanks for the tutorial!

Re: How To: Include Summary Info In Saved Games

Posted: Wed Dec 09, 2020 4:00 pm
by Tony Li
Glad it was helpful!

Re: How To: Include Summary Info In Saved Games

Posted: Fri Dec 11, 2020 1:39 pm
by hellwalker
Hello,
I made a code like this based on example:

Code: Select all

 if (SaveSystem.HasSavedGameInSlot(_SlotID) == false)
                return null;
            SavedGameData _SavedGameData = SaveSystem.storer.RetrieveSavedGameData(_SlotID);
            
and the SaveSystem.storer.RetrieveSavedGameData(_SlotID); is giving me an error.

I debugged and in SaveSystem.cs in this function
public static T Deserialize<T>(string s, T data = default(T))
{
return serializer.Deserialize<T>(s, data);
}

the data is being passed as null. Could this be the bug? Or am I doing something wrong?
I use playerprefs storer.

Code: Select all

ArgumentException: JSON parse error: Invalid value.
UnityEngine.JsonUtility.FromJson (System.String json, System.Type type) (at <1386288601af43018501cce2912f52f4>:0)
UnityEngine.JsonUtility.FromJson[T] (System.String json) (at <1386288601af43018501cce2912f52f4>:0)
PixelCrushers.JsonDataSerializer.Deserialize[T] (System.String s, T data) (at Assets/Plugins/Pixel Crushers/Common/Scripts/Save System/Serializers/JsonDataSerializer.cs:40)
PixelCrushers.SaveSystem.Deserialize[T] (System.String s, T data) (at Assets/Plugins/Pixel Crushers/Common/Scripts/Save System/SaveSystem.cs:865)
PixelCrushers.PlayerPrefsSavedGameDataStorer.RetrieveSavedGameData (System.Int32 slotNumber) (at Assets/Plugins/Pixel Crushers/Common/Scripts/Save System/Storers/PlayerPrefsSavedGameDataStorer.cs:75)
MemoryGame.SaveManager.GetSaveMetada (System.Int32 _SlotID) (at Assets/!Game/Scripts/SaveSystem/SaveManager.cs:174)
MemoryGame.SaveManager.GetSaveMetadas (System.Collections.Generic.List`1[T] _Slots) (at Assets/!Game/Scripts/SaveSystem/SaveManager.cs:165)
MemoryGame.SaveManager.GetSaveMetadas () (at Assets/!Game/Scripts/SaveSystem/SaveManager.cs:155)
MemoryGame.SaveFileList.GetSaveFiles () (at Assets/!Game/Scripts/Menus/SaveFileList.cs:43)
MemoryGame.SaveFileList.UpdateList () (at Assets/!Game/Scripts/Menus/SaveFileList.cs:18)
MemoryGame.SaveLoadMenu.ShowMenu (System.Boolean _LayeredMenu) (at Assets/!Game/Scripts/Menus/SaveLoadMenu.cs:14)
MemoryGame.MenuButtonCommands.LoadClicked () (at Assets/!Game/Scripts/Menus/MenuButtonCommands.cs:52)
UnityEngine.Events.InvokableCall.Invoke () (at <8691ad7005ed4755a1828378ff0b52b1>:0)
UnityEngine.Events.UnityEvent.Invoke () (at <8691ad7005ed4755a1828378ff0b52b1>:0)
UnityEngine.UI.Button.Press () (at C:/Program Files/Unity/Hub/Editor/2019.4.11f1/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/UI/Core/Button.cs:68)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at C:/Program Files/Unity/Hub/Editor/2019.4.11f1/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/UI/Core/Button.cs:110)
UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/Program Files/Unity/Hub/Editor/2019.4.11f1/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/EventSystem/ExecuteEvents.cs:50)
UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) (at C:/Program Files/Unity/Hub/Editor/2019.4.11f1/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/EventSystem/ExecuteEvents.cs:261)
UnityEngine.EventSystems.EventSystem:Update() (at C:/Program Files/Unity/Hub/Editor/2019.4.11f1/Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui/Runtime/EventSystem/EventSystem.cs:377)

Re: How To: Include Summary Info In Saved Games

Posted: Fri Dec 11, 2020 2:21 pm
by Tony Li
Hi,

Have you ticked the PlayerPrefs Saved Game Data Storer's Encrypt checkbox? If so, maybe it's not able to decrypt the data. This could happen if you changed the encryption password after saving the game.

Which parameter is being passed as null? s or data?

Re: [HOWTO] How To: Include Summary Info In Saved Games

Posted: Sat Oct 29, 2022 1:53 am
by BWLGeorge
Having an issue with this where I modified the Saver template with this bit of code and I'm getting the error, "The name 'SceneManager' does not exist in the current context"

Re: [HOWTO] How To: Include Summary Info In Saved Games

Posted: Sat Oct 29, 2022 8:22 am
by Tony Li
Hi,

Try putting this at the top of your script:

Code: Select all

using UnityEngine.SceneManagement;

Re: [HOWTO] How To: Include Summary Info In Saved Games

Posted: Fri Dec 23, 2022 8:07 am
by hamatchi23
I hope there's a video tutorial I am really a noob at programming :(

Re: [HOWTO] How To: Include Summary Info In Saved Games

Posted: Fri Dec 23, 2022 10:04 am
by Tony Li
I'll add that to the list of tutorials to record.