diff --git a/Assets/Scripts/DataPersistence/Data/GameData.cs b/Assets/Scripts/DataPersistence/Data/GameData.cs index 3efdecc5d35ca3653eac2a8f826bcd506c6cfe9e..16804de39d1636629aca27e8619839518e02020c 100644 --- a/Assets/Scripts/DataPersistence/Data/GameData.cs +++ b/Assets/Scripts/DataPersistence/Data/GameData.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -5,6 +6,9 @@ using UnityEngine; [System.Serializable] public class GameData { + public string saveName; + public DateTime currentTimeUtc; + public int currentLevel; public Vector3 playerPosition; @@ -27,8 +31,6 @@ public class GameData public List<PetData> pet = new List<PetData>(); - // the values defined in this constructor will be the default values - // the game starts with when there's no data to load public GameData() { @@ -42,4 +44,9 @@ public class PetData public int currentHealth; public int damagePerShot; public float speed; + + public PetData() + { + + } } \ No newline at end of file diff --git a/Assets/Scripts/DataPersistence/DataPersistenceManager.cs b/Assets/Scripts/DataPersistence/DataPersistenceManager.cs index 488d07c0bf30aa5384326e0eddfdeb31e1562661..6cc908cb4a89e0a256a0d72b876c0d9559f20b33 100644 --- a/Assets/Scripts/DataPersistence/DataPersistenceManager.cs +++ b/Assets/Scripts/DataPersistence/DataPersistenceManager.cs @@ -12,6 +12,8 @@ public class DataPersistenceManager : MonoBehaviour private List<IDataPersistence> dataPersistenceObjects; private FileDataHandler dataHandler; + private string selectedProfileId = "test"; + public static DataPersistenceManager instance { get; private set; } private void Awake() @@ -38,7 +40,7 @@ public class DataPersistenceManager : MonoBehaviour public void LoadGame() { // load any saved data from a file using data handler - this.gameData = dataHandler.Load(); + this.gameData = dataHandler.Load(selectedProfileId); // if no data can be loaded, initialize to a new game if (this.gameData == null) @@ -63,7 +65,7 @@ public class DataPersistenceManager : MonoBehaviour Debug.Log("Saved game data"); // save that data to a file using data handler - dataHandler.Save(gameData); + dataHandler.Save(gameData, selectedProfileId); } //private void OnApplicationQuit() @@ -76,4 +78,14 @@ public class DataPersistenceManager : MonoBehaviour IEnumerable<IDataPersistence> dataPersistenceObjects = FindObjectsOfType<MonoBehaviour>().OfType<IDataPersistence>(); return new List<IDataPersistence>(dataPersistenceObjects); } + + public bool HasGameData() + { + return gameData != null; + } + + public Dictionary<string, GameData> GetAllProfilesGameData() + { + return dataHandler.LoadAllProfiles(); + } } diff --git a/Assets/Scripts/DataPersistence/FileDataHandler.cs b/Assets/Scripts/DataPersistence/FileDataHandler.cs index efc010b887a58962072feeb54c22b872e38f2ac8..dcc2d88544b1014e469d1c31227a9bc5cee7d20e 100644 --- a/Assets/Scripts/DataPersistence/FileDataHandler.cs +++ b/Assets/Scripts/DataPersistence/FileDataHandler.cs @@ -15,10 +15,10 @@ public class FileDataHandler this.dataFileName = dataFileName; } - public GameData Load() + public GameData Load(string profileId) { // use Path.combine to account for different OS's having different path separators - string fullPath = Path.Combine(dataDirPath, dataFileName); + string fullPath = Path.Combine(dataDirPath, profileId, dataFileName); GameData loadedData = null; if (File.Exists(fullPath)) { @@ -45,10 +45,10 @@ public class FileDataHandler return loadedData; } - public void Save(GameData data) + public void Save(GameData data, string profileId) { // use Path.combine to account for different OS's having different path separators - string fullPath = Path.Combine(dataDirPath, dataFileName); + string fullPath = Path.Combine(dataDirPath, profileId, dataFileName); try { // create the directory the file will be written to if it doesn't already exist @@ -71,4 +71,40 @@ public class FileDataHandler Debug.LogError("Error occured when trying to save data to file: " + fullPath + "\n" + e); } } + + public Dictionary<string, GameData> LoadAllProfiles() + { + Dictionary<string, GameData> profileDictionary = new Dictionary<string, GameData>(); + + // loop over all directory names in the data directory path + IEnumerable<DirectoryInfo> dirInfos = new DirectoryInfo(dataDirPath).EnumerateDirectories(); + foreach (DirectoryInfo dirInfo in dirInfos) + { + string profileId = dirInfo.Name; + + // defensife programming - check if the data file exists + // if it doesn't, then this folder isn't a profile and should be skipped + string fullPath = Path.Combine(dataDirPath, profileId, dataFileName); + if (!File.Exists(fullPath)) + { + Debug.LogWarning("Skipping directory when loading all profiles because it doesn't contain data: " + profileId); + continue; + } + + // load the fame data for this profile and put it in the dictionary + GameData profileData = Load(profileId); + + // defensive programming - ensure the profile data isn't null + // because if it is then something went wrong and we should let ourselves know + if (profileData != null) + { + profileDictionary.Add(profileId, profileData); + } else + { + Debug.LogError("Tried to load profile but something went wrong. ProfileId: " + profileId); + } + } + + return profileDictionary; + } } diff --git a/Assets/Scripts/Save.meta b/Assets/Scripts/Save.meta new file mode 100644 index 0000000000000000000000000000000000000000..42ecb6a360aed0e890cf48a3983b84e777d30e02 --- /dev/null +++ b/Assets/Scripts/Save.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0307f5f70bbd57245b5756a9fd0b65d1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Save/SaveSlot.cs b/Assets/Scripts/Save/SaveSlot.cs new file mode 100644 index 0000000000000000000000000000000000000000..58c3ff1d3c9bfcf3ca526a81f95a75edd83356f3 --- /dev/null +++ b/Assets/Scripts/Save/SaveSlot.cs @@ -0,0 +1,39 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using TMPro; + +public class SaveSlot : MonoBehaviour +{ + [Header("Profile")] + [SerializeField] private string profileId = ""; + + [Header("Content")] + + [SerializeField] private GameObject noDataContent; + [SerializeField] private GameObject hasDataContent; + [SerializeField] private TextMeshProUGUI saveNameText; + [SerializeField] private TextMeshProUGUI timestampText; + + public void SetData (GameData data) + { + // there's no data for this profileId + if (data == null) + { + noDataContent.SetActive(true); + hasDataContent.SetActive(false); + } + // there is data for this profileId + else + { + noDataContent.SetActive(false); + hasDataContent.SetActive(true); + } + } + + public string GetProfileId() + { + return this.profileId; + } + +} diff --git a/Assets/Scripts/Save/SaveSlot.cs.meta b/Assets/Scripts/Save/SaveSlot.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..882e8055e1c2d272a9473ccfc4d2c51c5a8293e8 --- /dev/null +++ b/Assets/Scripts/Save/SaveSlot.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2173f7f1b7811c040be039d8cb6be761 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Save/SaveSlotsMenu.cs b/Assets/Scripts/Save/SaveSlotsMenu.cs new file mode 100644 index 0000000000000000000000000000000000000000..01742e247462b320733507001c84d6ae43c2361a --- /dev/null +++ b/Assets/Scripts/Save/SaveSlotsMenu.cs @@ -0,0 +1,27 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class SaveSlotsMenu : MonoBehaviour +{ + private SaveSlot[] saveSlots; + + private void Awake() + { + saveSlots = this.GetComponentsInChildren<SaveSlot>(); + } + + public void ActivateMenu() + { + // load all of the profiles that exist + Dictionary<string, GameData> profilesGameData = DataPersistenceManager.instance.GetAllProfilesGameData(); + + // loop through each save slot in the UI and set the content appropriately + foreach (SaveSlot saveSlot in saveSlots) + { + GameData profileData = null; + profilesGameData.TryGetValue(saveSlot.GetProfileId(), out profileData); + saveSlot.SetData(profileData); + } + } +} diff --git a/Assets/Scripts/Save/SaveSlotsMenu.cs.meta b/Assets/Scripts/Save/SaveSlotsMenu.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..07ca03b7d6297bb228266f43647a59cf2c8b9196 --- /dev/null +++ b/Assets/Scripts/Save/SaveSlotsMenu.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0175ea50dd35de04dae7a0bff1648fbf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: