Пример #1
0
 public SaveFile(SaveFile _saveFile)
 {
     ID = _saveFile.ID;
     label = _saveFile.label;
     screenShot = _saveFile.screenShot;
     fileName = _saveFile.fileName;
     isAutoSave = _saveFile.isAutoSave;
     updatedTime = _saveFile.updatedTime;
 }
Пример #2
0
 public string GetSlotLabel(int elementSlot, int saveID, bool useSaveID, SaveFile[] saveFiles)
 {
     if (Application.isPlaying)
     {
         if (useSaveID)
         {
             foreach (SaveFile saveFile in saveFiles)
             {
                 if (saveFile.ID == saveID)
                 {
                     return saveFile.label;
                 }
             }
         }
         else if (elementSlot >= 0)
         {
             if (elementSlot < saveFiles.Length)
             {
                 return saveFiles [elementSlot].label;
             }
         }
         return "";
     }
     return ("Save test (01/01/2001 12:00:00)");
 }
Пример #3
0
 public Texture2D GetScreenshot(int elementSlot, int saveID, bool useSaveID, SaveFile[] saveFiles)
 {
     if (Application.isPlaying)
     {
         if (useSaveID)
         {
             foreach (SaveFile saveFile in saveFiles)
             {
                 if (saveFile.ID == saveID)
                 {
                     return saveFile.screenShot;
                 }
             }
         }
         else if (elementSlot >= 0)
         {
             if (elementSlot < saveFiles.Length)
             {
                 return saveFiles [elementSlot].screenShot;
             }
         }
     }
     return null;
 }
Пример #4
0
        public void GatherSaveFiles()
        {
            foundSaveFiles = new List<SaveFile>();

            for (int i=0; i<50; i++)
            {
                bool isAutoSave = false;

                #if UNITY_WEBPLAYER || UNITY_WINRT || UNITY_WII

                if (PlayerPrefs.HasKey (GetProjectName () + GetSaveIDFile (i)))
                {
                    string label = "Save " + i.ToString ();
                    if (i == 0)
                    {
                        label = "Autosave";
                        isAutoSave = true;
                    }
                    foundSaveFiles.Add (new SaveFile (i, label, null, "", isAutoSave, 0));
                }

                #else

                string filename = saveDirectory + Path.DirectorySeparatorChar.ToString () + GetProjectName () + GetSaveIDFile (i) + GetSaveExtension ();
                if (File.Exists (filename))
                {
                    int updateTime = 0;
                    string label = "Save " + i.ToString ();
                    if (i == 0)
                    {
                        label = "Autosave";
                        isAutoSave = true;
                    }

                    if (KickStarter.settingsManager.saveTimeDisplay != SaveTimeDisplay.None)
                    {
                        DirectoryInfo dir = new DirectoryInfo (saveDirectory);
                        FileInfo[] info = dir.GetFiles (GetProjectName () + GetSaveIDFile (i) + GetSaveExtension ());

                        if (!isAutoSave)
                        {
                            System.TimeSpan t = info[0].LastWriteTime - new System.DateTime (2015, 1, 1);
                            updateTime = (int) t.TotalSeconds;
                        }

                        string creationTime = info[0].LastWriteTime.ToShortDateString ();
                        if (KickStarter.settingsManager.saveTimeDisplay == SaveTimeDisplay.TimeAndDate)
                        {
                            creationTime += " " + System.DateTime.Now.ToShortTimeString ();
                        }

                        label += " (" + creationTime + ")";
                    }

                    Texture2D screenShot = null;
                    if (KickStarter.settingsManager.takeSaveScreenshots)
                    {
                        screenShot = Serializer.LoadScreenshot (GetSaveScreenshotName (i));
                    }

                    foundSaveFiles.Add (new SaveFile (i, label, screenShot, filename, isAutoSave, updateTime));
                }

                #endif
            }

            if (KickStarter.settingsManager.orderSavesByUpdateTime)
            {
                foundSaveFiles.Sort (delegate (SaveFile a, SaveFile b) {return a.updatedTime.CompareTo (b.updatedTime);});
            }

            // Now get save file labels
            if (Options.optionsData.saveFileNames != "")
            {
                string[] profilesArray = Options.optionsData.saveFileNames.Split ("|"[0]);
                foreach (string chunk in profilesArray)
                {
                    string[] chunkData = chunk.Split (":"[0]);

                    int _id = 0;
                    int.TryParse (chunkData[0], out _id);
                    string _label = chunkData[1];

                    for (int i=0; i<Mathf.Min (50, foundSaveFiles.Count); i++)
                    {
                        if (foundSaveFiles[i].ID == _id)
                        {
                            SaveFile newSaveFile = new SaveFile (foundSaveFiles [i]);
                            newSaveFile.SetLabel (_label);
                            foundSaveFiles[i] = newSaveFile;
                        }
                    }
                }
            }
        }
Пример #5
0
        public bool SaveSaveGame(int saveID, bool overwriteLabel = true, string newLabel = "")
        {
            if (GetNumSaves () >= KickStarter.settingsManager.maxSaves && !DoesSaveExist (saveID))
            {
                Debug.LogWarning ("Cannot save - maximum number of save files has already been reached.");
                return false;
            }

            CustomSaveHook ();
            KickStarter.levelStorage.StoreCurrentLevelData ();

            Player player = KickStarter.player;

            if (KickStarter.playerInput && KickStarter.runtimeInventory && KickStarter.sceneChanger && KickStarter.settingsManager && KickStarter.stateHandler)
            {
                if (saveData != null && saveData.playerData != null && saveData.playerData.Count > 0)
                {
                    foreach (PlayerData _data in saveData.playerData)
                    {
                        if (player != null && _data.playerID == player.ID)
                        {
                            saveData.playerData.Remove (_data);
                            break;
                        }
                    }
                }
                else
                {
                    saveData = new SaveData ();
                    saveData.mainData = new MainData ();
                    saveData.playerData = new List<PlayerData>();
                }

                PlayerData playerData = SavePlayerData (player);
                saveData.playerData.Add (playerData);

                // Main data
                saveData.mainData.cursorIsOff = KickStarter.stateHandler.cursorIsOff;
                saveData.mainData.inputIsOff = KickStarter.stateHandler.inputIsOff;
                saveData.mainData.interactionIsOff = KickStarter.stateHandler.interactionIsOff;
                saveData.mainData.menuIsOff = KickStarter.stateHandler.menuIsOff;
                saveData.mainData.movementIsOff = KickStarter.stateHandler.movementIsOff;
                saveData.mainData.cameraIsOff = KickStarter.stateHandler.cameraIsOff;
                saveData.mainData.triggerIsOff = KickStarter.stateHandler.triggerIsOff;
                saveData.mainData.playerIsOff = KickStarter.stateHandler.playerIsOff;

                saveData.mainData.movementMethod = (int) KickStarter.settingsManager.movementMethod;

                if (player != null)
                {
                    saveData.mainData.currentPlayerID = player.ID;
                }
                else
                {
                    saveData.mainData.currentPlayerID = KickStarter.settingsManager.GetEmptyPlayerID ();
                }

                saveData.mainData.timeScale = KickStarter.playerInput.timeScale;

                if (KickStarter.playerInput.activeArrows)
                {
                    saveData.mainData.activeArrows = Serializer.GetConstantID (KickStarter.playerInput.activeArrows.gameObject);
                }

                if (KickStarter.playerInput.activeConversation)
                {
                    saveData.mainData.activeConversation = Serializer.GetConstantID (KickStarter.playerInput.activeConversation.gameObject);
                }

                if (KickStarter.runtimeInventory.selectedItem != null)
                {
                    saveData.mainData.selectedInventoryID = KickStarter.runtimeInventory.selectedItem.id;
                    saveData.mainData.isGivingItem = KickStarter.runtimeInventory.IsGivingItem ();
                }
                else
                {
                    saveData.mainData.selectedInventoryID = -1;
                }
                RuntimeVariables.DownloadAll ();
                saveData.mainData.runtimeVariablesData = SaveSystem.CreateVariablesData (RuntimeVariables.GetAllVars (), false, VariableLocation.Global);

                saveData.mainData.menuLockData = CreateMenuLockData (PlayerMenus.GetMenus ());
                saveData.mainData.menuVisibilityData = CreateMenuVisibilityData (PlayerMenus.GetMenus ());
                saveData.mainData.menuElementVisibilityData = CreateMenuElementVisibilityData (PlayerMenus.GetMenus ());
                saveData.mainData.menuJournalData = CreateMenuJournalData (PlayerMenus.GetMenus ());

                string mainData = "";
                string levelData = "";

                if (SaveSystem.GetSaveMethod () == SaveMethod.XML)
                {
                    mainData = Serializer.SerializeObjectXML <SaveData> (saveData);
                    levelData = Serializer.SerializeObjectXML <List<SingleLevelData>> (KickStarter.levelStorage.allLevelData);
                }
                else
                {
                    mainData = Serializer.SerializeObjectBinary (saveData);
                    levelData = Serializer.SerializeObjectBinary (KickStarter.levelStorage.allLevelData);
                }
                string allData = mainData + "||" + levelData;

                Serializer.CreateSaveFile (GetSaveFileName (saveID), allData);

                // Update label
                if (overwriteLabel)
                {
                    GatherSaveFiles ();
                    for (int i=0; i<Mathf.Min (50, foundSaveFiles.Count); i++)
                    {
                        if (foundSaveFiles[i].ID == saveID)
                        {
                            SaveFile newSaveFile = new SaveFile (foundSaveFiles [i]);
                            if (newLabel.Length > 0)
                            {
                                newSaveFile.SetLabel (newLabel);
                            }
                            else
                            {
                                newSaveFile.SetLabel (GetDefaultSaveLabel (saveID));
                            }
                            foundSaveFiles[i] = newSaveFile;
                            break;
                        }
                    }
                }

                // Update PlayerPrefs
                Options.optionsData.lastSaveID = saveID;
                Options.UpdateSaveLabels (foundSaveFiles.ToArray ());

                #if !UNITY_WEBPLAYER && !UNITY_WINRT && !UNITY_WII
                if (KickStarter.settingsManager.takeSaveScreenshots)
                {
                    StartCoroutine ("TakeScreenshot", GetSaveScreenshotName (saveID));
                }
                else
                {
                    GatherSaveFiles ();
                }
                #else
                GatherSaveFiles ();
                #endif
            }
            else
            {
                if (KickStarter.playerInput == null)
                {
                    Debug.LogWarning ("Save failed - no PlayerInput found.");
                }
                if (KickStarter.runtimeInventory == null)
                {
                    Debug.LogWarning ("Save failed - no RuntimeInventory found.");
                }
                if (KickStarter.sceneChanger == null)
                {
                    Debug.LogWarning ("Save failed - no SceneChanger found.");
                }
                if (KickStarter.settingsManager == null)
                {
                    Debug.LogWarning ("Save failed - no Settings Manager found.");
                }
            }

            return true;
        }
Пример #6
0
        public void RenameSave(string newLabel, int saveIndex)
        {
            if (newLabel.Length == 0)
            {
                return;
            }

            GatherSaveFiles ();

            if (foundSaveFiles.Count > saveIndex && saveIndex >= 0)
            {
                SaveFile newSaveFile = new SaveFile (foundSaveFiles [saveIndex]);
                newSaveFile.SetLabel (newLabel);
                foundSaveFiles [saveIndex] = newSaveFile;
                Options.UpdateSaveLabels (foundSaveFiles.ToArray ());
            }
        }
Пример #7
0
        public static void UpdateSaveLabels(SaveFile[] foundSaveFiles)
        {
            System.Text.StringBuilder newSaveNameData = new System.Text.StringBuilder ();

            if (foundSaveFiles != null)
            {
                foreach (SaveFile saveFile in foundSaveFiles)
                {
                    newSaveNameData.Append (saveFile.ID.ToString ());
                    newSaveNameData.Append (":");
                    newSaveNameData.Append (saveFile.GetSafeLabel ());
                    newSaveNameData.Append ("|");
                }

                if (foundSaveFiles.Length > 0)
                {
                    newSaveNameData.Remove (newSaveNameData.Length - 1, 1);
                }
            }

            optionsData.saveFileNames = newSaveNameData.ToString ();
            SavePrefs ();
        }
Пример #8
0
        /**
         * <summary>Saves the game, once found to exist.</summary>
         * <param name = "saveID">The save ID to save</param>
         * <param name = "overwriteLabel">True if the label should be updated</param>
         * <param name = "newLabel">The new label, if it can be set. If blank, a default label will be generated.</param>
         * <returns>True if the save was successful</returns>
         */
        public bool SaveSaveGame(int saveID, bool overwriteLabel = true, string newLabel = "")
        {
            if (GetNumSaves () >= KickStarter.settingsManager.maxSaves && !DoesSaveExist (saveID))
            {
                ACDebug.LogWarning ("Cannot save - maximum number of save files has already been reached.");
                return false;
            }

            CustomSaveHook ();
            KickStarter.levelStorage.StoreCurrentLevelData ();

            Player player = KickStarter.player;

            if (KickStarter.playerInput && KickStarter.runtimeInventory && KickStarter.sceneChanger && KickStarter.settingsManager && KickStarter.stateHandler)
            {
                if (saveData != null && saveData.playerData != null && saveData.playerData.Count > 0)
                {
                    foreach (PlayerData _data in saveData.playerData)
                    {
                        if (player != null && _data.playerID == player.ID)
                        {
                            saveData.playerData.Remove (_data);
                            break;
                        }
                    }
                }
                else
                {
                    saveData = new SaveData ();
                    saveData.mainData = new MainData ();
                    saveData.playerData = new List<PlayerData>();
                }

                PlayerData playerData = SavePlayerData (player);
                saveData.playerData.Add (playerData);

                // Main data
                saveData.mainData = KickStarter.stateHandler.SaveMainData (saveData.mainData);
                saveData.mainData.movementMethod = (int) KickStarter.settingsManager.movementMethod;

                if (player != null)
                {
                    saveData.mainData.currentPlayerID = player.ID;
                }
                else
                {
                    saveData.mainData.currentPlayerID = KickStarter.settingsManager.GetEmptyPlayerID ();
                }

                saveData.mainData = KickStarter.playerInput.SaveMainData (saveData.mainData);
                saveData.mainData = KickStarter.runtimeInventory.SaveMainData (saveData.mainData);
                saveData.mainData = KickStarter.runtimeVariables.SaveMainData (saveData.mainData);
                saveData.mainData = KickStarter.playerMenus.SaveMainData (saveData.mainData);

                string mainData = Serializer.SerializeObject <SaveData> (saveData, true);
                string levelData = Serializer.SerializeAllRoomData (KickStarter.levelStorage.allLevelData);

                string allData = mainData + "||" + levelData;

                Serializer.CreateSaveFile (GetSaveFileName (saveID), allData);

                // Update label
                if (overwriteLabel)
                {
                    GatherSaveFiles ();
                    for (int i=0; i<Mathf.Min (50, foundSaveFiles.Count); i++)
                    {
                        if (foundSaveFiles[i].ID == saveID)
                        {
                            SaveFile newSaveFile = new SaveFile (foundSaveFiles [i]);
                            if (newLabel.Length > 0)
                            {
                                newSaveFile.SetLabel (newLabel);
                            }
                            else
                            {
                                newSaveFile.SetLabel (GetDefaultSaveLabel (saveID));
                            }
                            foundSaveFiles[i] = newSaveFile;
                            break;
                        }
                    }
                }

                // Update PlayerPrefs
                Options.optionsData.lastSaveID = saveID;
                Options.UpdateSaveLabels (foundSaveFiles.ToArray ());

                #if !UNITY_WEBPLAYER && !UNITY_WINRT && !UNITY_WII
                if (KickStarter.settingsManager.takeSaveScreenshots)
                {
                    StartCoroutine ("TakeScreenshot", GetSaveScreenshotName (saveID));
                }
                else
                {
                    GatherSaveFiles ();
                }
                #else
                GatherSaveFiles ();
                #endif
            }
            else
            {
                if (KickStarter.playerInput == null)
                {
                    ACDebug.LogWarning ("Save failed - no PlayerInput found.");
                }
                if (KickStarter.runtimeInventory == null)
                {
                    ACDebug.LogWarning ("Save failed - no RuntimeInventory found.");
                }
                if (KickStarter.sceneChanger == null)
                {
                    ACDebug.LogWarning ("Save failed - no SceneChanger found.");
                }
                if (KickStarter.settingsManager == null)
                {
                    ACDebug.LogWarning ("Save failed - no Settings Manager found.");
                }
            }

            return true;
        }
Пример #9
0
        private void SaveFileGUI()
        {
            iSaveFileHandler    saveFileHandler          = SaveSystem.SaveFileHandler;
            iOptionsFileHandler optionsFileHandler       = Options.OptionsFileHandler;
            iFileFormatHandler  fileFormatHandler        = SaveSystem.FileFormatHandler;
            iFileFormatHandler  optionsFileFormatHandler = SaveSystem.OptionsFileFormatHandler;

            if (optionsFileHandler == null)
            {
                EditorGUILayout.HelpBox("No Options File Handler assigned - one must be set in order to locate Profile Data.", MessageType.Warning);
                return;
            }

            if (saveFileHandler == null)
            {
                EditorGUILayout.HelpBox("No Save File Handler assigned - one must be set in order to locate Save Data.", MessageType.Warning);
                return;
            }

            EditorGUILayout.BeginVertical(CustomStyles.thinBox);
            showHandlers = CustomGUILayout.ToggleHeader(showHandlers, "File and format handlers");
            if (showHandlers)
            {
                if (saveFileHandler != null)
                {
                    EditorGUILayout.LabelField("Save file location:", saveFileHandler.GetType().Name);
                }

                if (optionsFileHandler != null)
                {
                    EditorGUILayout.LabelField("Options location:", optionsFileHandler.GetType().Name);
                }

                if (fileFormatHandler != null)
                {
                    EditorGUILayout.LabelField("File format:", fileFormatHandler.GetType().Name);
                }

                if (optionsFileFormatHandler != null && fileFormatHandler == null || (optionsFileFormatHandler.GetType().Name != fileFormatHandler.GetType().Name))
                {
                    EditorGUILayout.LabelField("Options format:", optionsFileFormatHandler.GetType().Name);
                }

                EditorGUILayout.HelpBox("Save format and location handlers can be modified through script - see the Manual's 'Custom save formats and handling' chapter.", MessageType.Info);
            }
            CustomGUILayout.EndVertical();

            if (settingsManager.useProfiles)
            {
                EditorGUILayout.Space();

                EditorGUILayout.BeginVertical(CustomStyles.thinBox);
                showProfiles = CustomGUILayout.ToggleHeader(showProfiles, "Profiles");
                if (showProfiles)
                {
                    bool foundSome = false;

                    for (int profileID = 0; profileID < Options.maxProfiles; profileID++)
                    {
                        if (optionsFileHandler.DoesProfileExist(profileID))
                        {
                            foundSome = true;
                            OptionsData tempOptionsData = Options.LoadPrefsFromID(profileID, false, false);

                            string label = profileID.ToString() + ": " + tempOptionsData.label;
                            if (profileID == Options.GetActiveProfileID())
                            {
                                label += " (ACTIVE)";
                            }

                            if (GUILayout.Toggle(selectedProfileID == profileID, label, "Button"))
                            {
                                if (selectedProfileID != profileID)
                                {
                                    selectedProfileID = profileID;
                                    selectedSaveIndex = -1;
                                    foundSaveFiles.Clear();
                                }
                            }
                        }
                    }

                    if (!foundSome)
                    {
                        selectedProfileID = -1;
                        EditorGUILayout.HelpBox("No save profiles found.", MessageType.Warning);
                    }
                }
                CustomGUILayout.EndVertical();
            }
            else
            {
                selectedProfileID = 0;
            }

            if (selectedProfileID < 0 || !optionsFileHandler.DoesProfileExist(selectedProfileID))
            {
                EditorGUILayout.HelpBox("No save profiles found! Run the game to create a new save profile", MessageType.Warning);
                return;
            }

            EditorGUILayout.Space();

            EditorGUILayout.BeginVertical(CustomStyles.thinBox);
            showProfile = CustomGUILayout.ToggleHeader(showProfile, "Profile " + selectedProfileID + ": Properties");
            if (showProfile)
            {
                OptionsData prefsData = GetPrefsData(selectedProfileID);
                if (prefsData != null)
                {
                    EditorGUILayout.LabelField("Label:", prefsData.label);
                    EditorGUILayout.LabelField("ID:", prefsData.ID.ToString());
                    EditorGUILayout.LabelField("Language:", prefsData.language.ToString());
                    if (prefsData.language != prefsData.voiceLanguage)
                    {
                        EditorGUILayout.LabelField("Voice language:", prefsData.voiceLanguage.ToString());
                    }
                    EditorGUILayout.LabelField("Show subtitles:", prefsData.showSubtitles.ToString());
                    EditorGUILayout.LabelField("SFX volume:", prefsData.sfxVolume.ToString());
                    EditorGUILayout.LabelField("Music volume:", prefsData.musicVolume.ToString());
                    EditorGUILayout.LabelField("Speech volume:", prefsData.speechVolume.ToString());

                    if (KickStarter.variablesManager != null)
                    {
                        List <GVar> linkedVariables = SaveSystem.UnloadVariablesData(prefsData.linkedVariables, KickStarter.variablesManager.vars, true);
                        foreach (GVar linkedVariable in linkedVariables)
                        {
                            if (linkedVariable.link == VarLink.OptionsData)
                            {
                                EditorGUILayout.LabelField(linkedVariable.label + ":", linkedVariable.GetValue());
                            }
                        }
                    }
                    else
                    {
                        EditorGUILayout.LabelField("Linked Variables:", prefsData.linkedVariables);
                    }

                    EditorGUILayout.BeginHorizontal();
                    if (settingsManager.useProfiles)
                    {
                        GUI.enabled = (selectedProfileID != Options.GetActiveProfileID());
                        if (GUILayout.Button("Make active"))
                        {
                            SwitchActiveProfile(selectedProfileID);
                        }
                        GUI.enabled = true;
                    }
                    if (GUILayout.Button("Delete profile"))
                    {
                        bool canDelete = EditorUtility.DisplayDialog("Delete profile?", "Are you sure you want to delete profile #" + selectedProfileID + "? This operation cannot be undone.", "Yes", "No");
                        if (canDelete)
                        {
                            Options.DeleteProfilePrefs(selectedProfileID);
                        }
                    }
                    EditorGUILayout.EndHorizontal();
                }
            }
            CustomGUILayout.EndVertical();

            EditorGUILayout.Space();

            foundSaveFiles = saveFileHandler.GatherSaveFiles(selectedProfileID);

            EditorGUILayout.BeginVertical(CustomStyles.thinBox);
            showSaves = CustomGUILayout.ToggleHeader(showSaves, "Save game files");
            if (showSaves)
            {
                if (foundSaveFiles != null)
                {
                    for (int saveIndex = 0; saveIndex < foundSaveFiles.Count; saveIndex++)
                    {
                        SaveFile saveFile = foundSaveFiles[saveIndex];
                        string   label    = saveFile.saveID.ToString() + ": " + saveFile.label;

                        if (GUILayout.Toggle(selectedSaveIndex == saveIndex, label, "Button"))
                        {
                            selectedSaveIndex = saveIndex;
                        }
                    }
                }

                if (foundSaveFiles == null || foundSaveFiles.Count == 0)
                {
                    selectedSaveIndex = -1;
                    EditorGUILayout.HelpBox("No save game files found.", MessageType.Warning);
                }

                EditorGUILayout.Space();
                EditorGUILayout.BeginHorizontal();
                GUI.enabled = Application.isPlaying;
                if (GUILayout.Button("Autosave"))
                {
                    if (!PlayerMenus.IsSavingLocked(null, true))
                    {
                        SwitchActiveProfile(selectedProfileID);
                        SaveSystem.SaveAutoSave();
                    }
                }
                if (GUILayout.Button("Save new"))
                {
                    if (!PlayerMenus.IsSavingLocked(null, true))
                    {
                        SwitchActiveProfile(selectedProfileID);
                        SaveSystem.SaveNewGame();
                    }
                }
                GUI.enabled = (foundSaveFiles != null && foundSaveFiles.Count > 0);
                if (GUILayout.Button("Delete all saves"))
                {
                    bool canDelete = EditorUtility.DisplayDialog("Delete all save files?", "Are you sure you want to delete all save files? This operation cannot be undone.", "Yes", "No");
                    if (canDelete)
                    {
                        saveFileHandler.DeleteAll(selectedProfileID);
                    }
                }
                CustomGUILayout.EndVertical();
            }
            CustomGUILayout.EndVertical();

            if (selectedSaveIndex < 0 || foundSaveFiles == null || selectedSaveIndex >= foundSaveFiles.Count)
            {
                return;
            }

            EditorGUILayout.Space();

            SaveFile selectedSaveFile = foundSaveFiles[selectedSaveIndex];

            EditorGUILayout.BeginVertical(CustomStyles.thinBox);
            showSave = CustomGUILayout.ToggleHeader(showSave, "Save game " + selectedSaveIndex + ": Properties");
            if (showSave)
            {
                EditorGUILayout.LabelField("Label:", selectedSaveFile.label);
                EditorGUILayout.LabelField("ID:", selectedSaveFile.saveID.ToString());

                CustomGUILayout.MultiLineLabelGUI("Filename:", selectedSaveFile.fileName);

                EditorGUILayout.LabelField("Timestamp:", selectedSaveFile.updatedTime.ToString());
                if (!string.IsNullOrEmpty(selectedSaveFile.screenshotFilename))
                {
                    CustomGUILayout.MultiLineLabelGUI("Filename:", selectedSaveFile.screenshotFilename);
                }
                EditorGUILayout.LabelField("Is auto-save?", selectedSaveFile.isAutoSave.ToString());

                GUILayout.BeginHorizontal();
                GUI.enabled = Application.isPlaying;
                if (GUILayout.Button("Load"))
                {
                    SwitchActiveProfile(selectedProfileID);
                    SaveSystem.LoadGame(0, selectedSaveFile.saveID, true);
                }
                if (GUILayout.Button("Save over"))
                {
                    if (!PlayerMenus.IsSavingLocked(null, true))
                    {
                        SwitchActiveProfile(selectedProfileID);
                        SaveSystem.SaveGame(0, selectedSaveFile.saveID, true);
                    }
                }
                GUI.enabled = true;

                if (GUILayout.Button("Delete"))
                {
                    bool canDelete = EditorUtility.DisplayDialog("Delete save file?", "Are you sure you want to delete the save file " + selectedSaveFile.label + "? This operation cannot be undone.", "Yes", "No");
                    if (canDelete)
                    {
                        saveFileHandler.Delete(selectedSaveFile);
                    }
                }
                GUILayout.EndHorizontal();
            }
            CustomGUILayout.EndVertical();

            EditorGUILayout.Space();

            EditorGUILayout.BeginVertical(CustomStyles.thinBox);
            showSaveData = CustomGUILayout.ToggleHeader(showSaveData, "Save game " + selectedSaveIndex + ": Data");
            if (showSaveData)
            {
                if (GUI.changed || !runCache)
                {
                    CacheSaveData(saveFileHandler, selectedSaveFile);
                }

                if (cachedSaveData != null)
                {
                    cachedSaveData.ShowGUI();
                }

                if (cachedLevelData != null)
                {
                    for (int i = 0; i < cachedLevelData.Count; i++)
                    {
                        CustomGUILayout.DrawUILine();
                        EditorGUILayout.LabelField("Scene data " + i.ToString() + ":", CustomStyles.subHeader);
                        cachedLevelData[i].ShowGUI();
                    }
                }
            }
            CustomGUILayout.EndVertical();
        }