From 56072ce41735487e6583c2ff1d9186112d202ea0 Mon Sep 17 00:00:00 2001
From: MarcelRyan <marcel.ryan2004@gmail.com>
Date: Wed, 8 May 2024 15:54:56 +0700
Subject: [PATCH] [FEAT] multislot save

---
 Assets/Prefabs/SaveLoad/SaveSlot.prefab       |  75 +++++++++
 Assets/Scenes/MainMenu.unity                  | 155 +++++++++++++++++-
 Assets/Scripts/DataUtils/FileDataHandler.cs   |  41 ++++-
 Assets/Scripts/DataUtils/GameData.cs          |   3 +
 Assets/Scripts/MainMenu/MainMenu.cs           |  29 +++-
 Assets/Scripts/MainMenu/SaveSlot.cs           |  54 ++++++
 Assets/Scripts/MainMenu/SaveSlot.cs.meta      |  11 ++
 Assets/Scripts/MainMenu/SaveSlotsMenu.cs      |  85 ++++++++++
 Assets/Scripts/MainMenu/SaveSlotsMenu.cs.meta |  11 ++
 .../Managers/DataPersistenceManager.cs        |  33 +++-
 Assets/Scripts/Managers/PetManager.cs         |   1 +
 11 files changed, 483 insertions(+), 15 deletions(-)
 create mode 100644 Assets/Scripts/MainMenu/SaveSlot.cs
 create mode 100644 Assets/Scripts/MainMenu/SaveSlot.cs.meta
 create mode 100644 Assets/Scripts/MainMenu/SaveSlotsMenu.cs
 create mode 100644 Assets/Scripts/MainMenu/SaveSlotsMenu.cs.meta

diff --git a/Assets/Prefabs/SaveLoad/SaveSlot.prefab b/Assets/Prefabs/SaveLoad/SaveSlot.prefab
index 7bbd708..54af2fb 100644
--- a/Assets/Prefabs/SaveLoad/SaveSlot.prefab
+++ b/Assets/Prefabs/SaveLoad/SaveSlot.prefab
@@ -9,6 +9,8 @@ GameObject:
   serializedVersion: 6
   m_Component:
   - component: {fileID: 4462075335458235205}
+  - component: {fileID: 3788206663366542281}
+  - component: {fileID: 6304524442119744541}
   m_Layer: 5
   m_Name: SaveSlot
   m_TagString: Untagged
@@ -37,6 +39,79 @@ RectTransform:
   m_AnchoredPosition: {x: 0, y: 0}
   m_SizeDelta: {x: 100, y: 100}
   m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &3788206663366542281
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 758476949122428523}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 30434a3b4fc556648b11b93eb8b630bb, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  profileId: 
+  noDataContent: {fileID: 6632141333641643131}
+  hasDataContent: {fileID: 2954734089067325035}
+  saveTitle: {fileID: 3829560269998401059}
+  timestamp: {fileID: 4025853616981099334}
+--- !u!114 &6304524442119744541
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 758476949122428523}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_WrapAround: 0
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Selected
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 0}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 0}
+        m_TargetAssemblyTypeName: 
+        m_MethodName: 
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: 
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
 --- !u!1 &2954734089067325035
 GameObject:
   m_ObjectHideFlags: 0
diff --git a/Assets/Scenes/MainMenu.unity b/Assets/Scenes/MainMenu.unity
index 09a7bb0..d7eb10a 100644
--- a/Assets/Scenes/MainMenu.unity
+++ b/Assets/Scenes/MainMenu.unity
@@ -943,6 +943,10 @@ PrefabInstance:
       propertyPath: m_Name
       value: SaveSlot (1)
       objectReference: {fileID: 0}
+    - target: {fileID: 3788206663366542281, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: profileId
+      value: 1
+      objectReference: {fileID: 0}
     - target: {fileID: 4462075335458235205, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
       propertyPath: m_Pivot.x
       value: 0.5
@@ -1023,6 +1027,30 @@ PrefabInstance:
       propertyPath: m_LocalEulerAnglesHint.z
       value: 0
       objectReference: {fileID: 0}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Mode
+      value: 2
+      objectReference: {fileID: 0}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Target
+      value: 
+      objectReference: {fileID: 1184545944}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_MethodName
+      value: OnSaveSlotClicked
+      objectReference: {fileID: 0}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_TargetAssemblyTypeName
+      value: Nightmare.SaveSlotsMenu, Assembly-CSharp
+      objectReference: {fileID: 0}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Arguments.m_ObjectArgument
+      value: 
+      objectReference: {fileID: 1103158574}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Arguments.m_ObjectArgumentAssemblyTypeName
+      value: Nightmare.SaveSlot, Assembly-CSharp
+      objectReference: {fileID: 0}
     m_RemovedComponents: []
     m_RemovedGameObjects: []
     m_AddedGameObjects: []
@@ -2241,6 +2269,10 @@ PrefabInstance:
       propertyPath: m_Name
       value: SaveSlot (2)
       objectReference: {fileID: 0}
+    - target: {fileID: 3788206663366542281, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: profileId
+      value: 2
+      objectReference: {fileID: 0}
     - target: {fileID: 4462075335458235205, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
       propertyPath: m_Pivot.x
       value: 0.5
@@ -2321,6 +2353,30 @@ PrefabInstance:
       propertyPath: m_LocalEulerAnglesHint.z
       value: 0
       objectReference: {fileID: 0}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Mode
+      value: 2
+      objectReference: {fileID: 0}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Target
+      value: 
+      objectReference: {fileID: 1184545944}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_MethodName
+      value: OnSaveSlotClicked
+      objectReference: {fileID: 0}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_TargetAssemblyTypeName
+      value: Nightmare.SaveSlotsMenu, Assembly-CSharp
+      objectReference: {fileID: 0}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Arguments.m_ObjectArgument
+      value: 
+      objectReference: {fileID: 1475580265}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Arguments.m_ObjectArgumentAssemblyTypeName
+      value: Nightmare.SaveSlot, Assembly-CSharp
+      objectReference: {fileID: 0}
     m_RemovedComponents: []
     m_RemovedGameObjects: []
     m_AddedGameObjects: []
@@ -2488,7 +2544,19 @@ MonoBehaviour:
   m_TargetGraphic: {fileID: 699790892}
   m_OnClick:
     m_PersistentCalls:
-      m_Calls: []
+      m_Calls:
+      - m_Target: {fileID: 1184545944}
+        m_TargetAssemblyTypeName: Nightmare.SaveSlotsMenu, Assembly-CSharp
+        m_MethodName: OnBackClicked
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
 --- !u!114 &699790892
 MonoBehaviour:
   m_ObjectHideFlags: 0
@@ -4320,6 +4388,17 @@ RectTransform:
   m_AnchoredPosition: {x: 0, y: 0}
   m_SizeDelta: {x: 0, y: 0}
   m_Pivot: {x: 0, y: 0}
+--- !u!114 &1103158574 stripped
+MonoBehaviour:
+  m_CorrespondingSourceObject: {fileID: 3788206663366542281, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+  m_PrefabInstance: {fileID: 257482453}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 30434a3b4fc556648b11b93eb8b630bb, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
 --- !u!1 &1119580573
 GameObject:
   m_ObjectHideFlags: 0
@@ -4648,6 +4727,7 @@ GameObject:
   - component: {fileID: 1184545941}
   - component: {fileID: 1184545943}
   - component: {fileID: 1184545942}
+  - component: {fileID: 1184545944}
   m_Layer: 5
   m_Name: SaveSlotMenu
   m_TagString: Untagged
@@ -4716,6 +4796,20 @@ CanvasRenderer:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 1184545940}
   m_CullTransparentMesh: 1
+--- !u!114 &1184545944
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1184545940}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5a67c112b7ed6694dbdce2976d40aa77, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  menu: {fileID: 2052799349}
+  backButton: {fileID: 699790891}
 --- !u!1 &1261534167
 GameObject:
   m_ObjectHideFlags: 0
@@ -5337,6 +5431,17 @@ CanvasRenderer:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 1462508785}
   m_CullTransparentMesh: 0
+--- !u!114 &1475580265 stripped
+MonoBehaviour:
+  m_CorrespondingSourceObject: {fileID: 3788206663366542281, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+  m_PrefabInstance: {fileID: 620480409}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 30434a3b4fc556648b11b93eb8b630bb, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
 --- !u!1 &1495964236
 GameObject:
   m_ObjectHideFlags: 0
@@ -7304,6 +7409,7 @@ MonoBehaviour:
   settings: {fileID: 95415617}
   stats: {fileID: 1261534167}
   loadButton: {fileID: 1495964238}
+  saveSlotsMenu: {fileID: 1184545944}
 --- !u!114 &2052799350
 MonoBehaviour:
   m_ObjectHideFlags: 0
@@ -7953,6 +8059,10 @@ PrefabInstance:
       propertyPath: m_Name
       value: SaveSlot
       objectReference: {fileID: 0}
+    - target: {fileID: 3788206663366542281, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: profileId
+      value: 0
+      objectReference: {fileID: 0}
     - target: {fileID: 4462075335458235205, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
       propertyPath: m_Pivot.x
       value: 0.5
@@ -8033,6 +8143,38 @@ PrefabInstance:
       propertyPath: m_LocalEulerAnglesHint.z
       value: 0
       objectReference: {fileID: 0}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.size
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Mode
+      value: 2
+      objectReference: {fileID: 0}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Target
+      value: 
+      objectReference: {fileID: 1184545944}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_CallState
+      value: 2
+      objectReference: {fileID: 0}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_MethodName
+      value: OnSaveSlotClicked
+      objectReference: {fileID: 0}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_TargetAssemblyTypeName
+      value: Nightmare.SaveSlotsMenu, Assembly-CSharp
+      objectReference: {fileID: 0}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Arguments.m_ObjectArgument
+      value: 
+      objectReference: {fileID: 625701130674137700}
+    - target: {fileID: 6304524442119744541, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Arguments.m_ObjectArgumentAssemblyTypeName
+      value: Nightmare.SaveSlot, Assembly-CSharp
+      objectReference: {fileID: 0}
     m_RemovedComponents: []
     m_RemovedGameObjects: []
     m_AddedGameObjects: []
@@ -8043,6 +8185,17 @@ RectTransform:
   m_CorrespondingSourceObject: {fileID: 4462075335458235205, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
   m_PrefabInstance: {fileID: 625701130674137698}
   m_PrefabAsset: {fileID: 0}
+--- !u!114 &625701130674137700 stripped
+MonoBehaviour:
+  m_CorrespondingSourceObject: {fileID: 3788206663366542281, guid: 2242591e5b2a354478f707bfb2e08fad, type: 3}
+  m_PrefabInstance: {fileID: 625701130674137698}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 30434a3b4fc556648b11b93eb8b630bb, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
 --- !u!1660057539 &9223372036854775807
 SceneRoots:
   m_ObjectHideFlags: 0
diff --git a/Assets/Scripts/DataUtils/FileDataHandler.cs b/Assets/Scripts/DataUtils/FileDataHandler.cs
index 278d875..8687e55 100644
--- a/Assets/Scripts/DataUtils/FileDataHandler.cs
+++ b/Assets/Scripts/DataUtils/FileDataHandler.cs
@@ -15,7 +15,7 @@ public class FileDataHandler
         this.dataFileName = dataFileName;
     }
 
-    public GameData Load()
+    public GameData Load(string profileId)
     {
         string fullPath = Path.Combine(dataDirPath, dataFileName);
 
@@ -65,7 +65,44 @@ public class FileDataHandler
 
     }
 
-    public void Save(GameData data)
+    public Dictionary<string, GameData> loadAllProfiles()
+    {
+        Dictionary<string, GameData> profileDictionary = new Dictionary<string, GameData>();
+
+        // Loop over all directory names
+        IEnumerable<DirectoryInfo> dirInfos = new DirectoryInfo(dataDirPath).EnumerateDirectories();
+
+        foreach (DirectoryInfo dirInfo in dirInfos)
+        {
+            string profileId = dirInfo.Name;
+
+            // check if data exists
+            string fullPath = Path.Combine(dataDirPath, profileId, dataFileName);
+
+            if (!File.Exists(fullPath))
+            {
+                Debug.LogWarning("Skipping directory when loading all profiles because the data doesn't exist");
+                continue;
+            }
+
+            // Load Gamedata 
+            GameData profileData = Load(profileId);
+
+            if (profileData != null)
+            {
+                profileDictionary.Add(profileId, profileData);
+            } 
+            else
+            {
+                Debug.LogWarning("Something went wrong when loading the data.");
+            }
+
+        }
+
+        return profileDictionary;
+    }
+
+    public void Save(GameData data, string profileId)
     {
         string fullPath = Path.Combine(dataDirPath, dataFileName);
         try
diff --git a/Assets/Scripts/DataUtils/GameData.cs b/Assets/Scripts/DataUtils/GameData.cs
index 77c02a7..9355d8a 100644
--- a/Assets/Scripts/DataUtils/GameData.cs
+++ b/Assets/Scripts/DataUtils/GameData.cs
@@ -19,6 +19,7 @@ public class GameData
     public int currentScene;
     public int currentQuest;
     public float shopKeeperTime;
+    public string timestamp;
 
     // Constructor buat default values kalau new game
     public GameData()
@@ -36,6 +37,7 @@ public class GameData
         this.currentScene = 1;
         this.currentQuest = 0;
         this.shopKeeperTime = 120f;
+        this.timestamp = string.Empty;
     }
 
     public GameData(int currentScene)
@@ -53,6 +55,7 @@ public class GameData
         this.currentScene = currentScene;
         this.currentQuest = 0;
         this.shopKeeperTime = 120f;
+        this.timestamp = string.Empty;
     }
 
 }
diff --git a/Assets/Scripts/MainMenu/MainMenu.cs b/Assets/Scripts/MainMenu/MainMenu.cs
index 4001072..59d46cb 100644
--- a/Assets/Scripts/MainMenu/MainMenu.cs
+++ b/Assets/Scripts/MainMenu/MainMenu.cs
@@ -9,6 +9,7 @@ public class MainMenu : MonoBehaviour
     public GameObject settings;
     public GameObject stats;
     [SerializeField] private Button loadButton;
+    [SerializeField] private SaveSlotsMenu saveSlotsMenu;
 
     private void Start()
     {
@@ -43,9 +44,12 @@ public class MainMenu : MonoBehaviour
 
     public void PlayGame()
     {
-        Debug.Log("On New Game Clicked");
-        DataPersistenceManager.instance.NewGame();
-        LevelManager.Instance.LoadScene();
+        //Debug.Log("On New Game Clicked");
+        //DataPersistenceManager.instance.NewGame();
+        //LevelManager.Instance.LoadScene();
+
+        saveSlotsMenu.ActivateMenu(false);
+        this.DeactivateMenu();
     }
 
     public void QuitGame()
@@ -57,8 +61,21 @@ public class MainMenu : MonoBehaviour
     public void OnLoadGameClicked()
     {
         Debug.Log("OnLoadGame clicked");
-        DataPersistenceManager.instance.LoadGame();
-        DataPersistenceManager.instance.LoadGameClicked();
-        LevelManager.Instance.LoadScene();
+        //DataPersistenceManager.instance.LoadGame();
+        //DataPersistenceManager.instance.LoadGameClicked();
+        //LevelManager.Instance.LoadScene();
+        saveSlotsMenu.ActivateMenu(true);
+        this.DeactivateMenu();
+    }
+
+    public void ActivateMenu()
+    {
+        this.gameObject.SetActive(true);
+        saveSlotsMenu.DeactiveMenu();
+    }
+
+    public void DeactivateMenu()
+    {
+        this.gameObject.SetActive(false);
     }
 }
diff --git a/Assets/Scripts/MainMenu/SaveSlot.cs b/Assets/Scripts/MainMenu/SaveSlot.cs
new file mode 100644
index 0000000..fc22196
--- /dev/null
+++ b/Assets/Scripts/MainMenu/SaveSlot.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using TMPro;
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace Nightmare
+{
+    public class SaveSlot : MonoBehaviour
+    {
+        [Header("Profile")]
+        [SerializeField] private string profileId = "";
+
+        [Header("Content")]
+        [SerializeField] private GameObject noDataContent;
+        [SerializeField] private GameObject hasDataContent;
+        [SerializeField] private TextMeshProUGUI saveTitle;
+        [SerializeField] private TextMeshProUGUI timestamp;
+        private Button saveSlotButton;
+
+        public void Awake()
+        {
+            saveSlotButton = this.GetComponent<Button>();
+        }
+
+        public void SetData(GameData data)
+        {
+            if (data == null)
+            {
+                noDataContent.SetActive(true);
+                hasDataContent.SetActive(false);
+            }
+            else
+            {
+                noDataContent.SetActive(false);
+                hasDataContent.SetActive(true);
+
+                saveTitle.text = data.playerName;
+                timestamp.text = data.timestamp;
+            }
+        }
+
+        public string GetProfileId()
+        {
+            return profileId;
+        }
+
+        public void SetInteractable(bool interactable)
+        {
+            saveSlotButton.interactable = interactable;
+        }
+    }
+}
diff --git a/Assets/Scripts/MainMenu/SaveSlot.cs.meta b/Assets/Scripts/MainMenu/SaveSlot.cs.meta
new file mode 100644
index 0000000..3c63549
--- /dev/null
+++ b/Assets/Scripts/MainMenu/SaveSlot.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 30434a3b4fc556648b11b93eb8b630bb
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/MainMenu/SaveSlotsMenu.cs b/Assets/Scripts/MainMenu/SaveSlotsMenu.cs
new file mode 100644
index 0000000..0f62ee6
--- /dev/null
+++ b/Assets/Scripts/MainMenu/SaveSlotsMenu.cs
@@ -0,0 +1,85 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace Nightmare
+{
+
+    public class SaveSlotsMenu : MonoBehaviour
+    {
+        [Header("Menu Navigation")]
+        [SerializeField] private MainMenu menu;
+        private SaveSlot[] saveSlots;
+
+        [Header("Menu Buttons")]
+        [SerializeField] private Button backButton;
+
+        private bool isLoadingGame = false;
+
+
+        private void Awake()
+        {
+            saveSlots = this.GetComponentsInChildren<SaveSlot>();
+        }
+
+        public void OnBackClicked()
+        {
+            menu.ActivateMenu();
+        }
+
+        public void ActivateMenu(bool isLoadingGame)
+        {
+            this.gameObject.SetActive(true);
+            // Load all of the profiles
+            Dictionary<string, GameData> profiles = DataPersistenceManager.instance.GetAllProfilesGameData();
+
+            this.isLoadingGame = isLoadingGame;
+
+            // Loop through each save slot in the UI and set the content
+            foreach(SaveSlot saveSlot in saveSlots)
+            {
+                GameData profileData = null;
+                profiles.TryGetValue(saveSlot.GetProfileId(), out profileData);
+                saveSlot.SetData(profileData);
+                if (profileData == null && isLoadingGame)
+                {
+                    saveSlot.SetInteractable(false);
+                }
+                else
+                {
+                    saveSlot.SetInteractable(true);
+                }
+            }
+        }
+
+        public void OnSaveSlotClicked(SaveSlot saveSlot)
+        {
+            Debug.Log("OnSaveSlotClicked called");
+            DisableMenuButtons();
+
+            DataPersistenceManager.instance.ChangeSelectedProfile(saveSlot.GetProfileId());
+
+            if (!isLoadingGame)
+            {
+                DataPersistenceManager.instance.NewGame();
+            }
+
+            LevelManager.Instance.LoadScene();
+        }
+
+        public void DeactiveMenu()
+        {
+            this.gameObject.SetActive(false);
+        }
+
+        private void DisableMenuButtons()
+        {
+            foreach (SaveSlot saveSlot in saveSlots)
+            {
+                saveSlot.SetInteractable(false);
+            }
+            backButton.interactable = false;
+        }
+    }
+}
diff --git a/Assets/Scripts/MainMenu/SaveSlotsMenu.cs.meta b/Assets/Scripts/MainMenu/SaveSlotsMenu.cs.meta
new file mode 100644
index 0000000..f2c607c
--- /dev/null
+++ b/Assets/Scripts/MainMenu/SaveSlotsMenu.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5a67c112b7ed6694dbdce2976d40aa77
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Managers/DataPersistenceManager.cs b/Assets/Scripts/Managers/DataPersistenceManager.cs
index 46bf0d2..20a3767 100644
--- a/Assets/Scripts/Managers/DataPersistenceManager.cs
+++ b/Assets/Scripts/Managers/DataPersistenceManager.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using UnityEngine;
 using System.Linq;
 using UnityEngine.SceneManagement;
+using System;
 public class DataPersistenceManager : MonoBehaviour
 {
     [Header("File Storage Config")]
@@ -12,10 +13,12 @@ public class DataPersistenceManager : MonoBehaviour
     private GameData gameData;
     private List<IDataPersistence> dataPersistenceList;
     private GameData loadedGameData;
+    private string selectedProfile;
     private bool newGame = false;
     private bool loadGame = false;
     private bool saveSafeHouse = false;
     private bool hasSaved = false;
+    private const string PLAYER_NAME_KEY = "PlayerName";
 
     private void Awake()
     {
@@ -49,7 +52,7 @@ public class DataPersistenceManager : MonoBehaviour
         {
             if (!hasSaved)
             {
-                this.dataHandler.Save(this.loadedGameData);
+                this.dataHandler.Save(this.loadedGameData, this.selectedProfile);
             }
         }
     }
@@ -67,17 +70,17 @@ public class DataPersistenceManager : MonoBehaviour
             Debug.Log(hasSaved);
             if (!hasSaved)
             {
-                this.dataHandler.Save(this.loadedGameData);
+                this.dataHandler.Save(this.loadedGameData, this.selectedProfile);
                 this.gameData = this.loadedGameData;
             }
             else
             {
-                this.gameData = this.dataHandler.Load();
+                this.gameData = this.dataHandler.Load(this.selectedProfile);
             }
         }
         else if (hasSaved)
         {
-            this.gameData = this.dataHandler.Load();
+            this.gameData = this.dataHandler.Load(this.selectedProfile);
         }
     }
 
@@ -111,6 +114,12 @@ public class DataPersistenceManager : MonoBehaviour
         }
     }
 
+    public void ChangeSelectedProfile(string profile)
+    {
+        this.selectedProfile = profile;
+        LoadGame();
+    }
+
     public void NewGame()
     {
         this.gameData = new GameData();
@@ -133,7 +142,7 @@ public class DataPersistenceManager : MonoBehaviour
         // TODO - load saved data
         if (!newGame)
         {
-            this.gameData = dataHandler.Load();
+            this.gameData = dataHandler.Load(this.selectedProfile);
             this.loadedGameData = this.gameData;
         }
 
@@ -161,12 +170,14 @@ public class DataPersistenceManager : MonoBehaviour
             dataPersistenceList[i].SaveData(ref gameData);
         }
 
+        this.gameData.timestamp = DateTime.Now.ToString();
+
         Debug.Log("SaveHouse bool: " + this.saveSafeHouse);
 
         // TODO - save data to a file
         if (saveSafeHouse)
         {
-            dataHandler.Save(gameData);
+            dataHandler.Save(gameData, this.selectedProfile);
             saveSafeHouse = false;
             hasSaved = true;
         }
@@ -206,4 +217,14 @@ public class DataPersistenceManager : MonoBehaviour
         this.newGame = false;
         this.loadedGameData = gameData;
     }
+
+    public Dictionary<string, GameData> GetAllProfilesGameData()
+    {
+        return dataHandler.loadAllProfiles();
+    }
+
+    public void getPlayerName()
+    {
+        this.gameData.playerName = PlayerPrefs.GetString(PLAYER_NAME_KEY, "");
+    }
 }
diff --git a/Assets/Scripts/Managers/PetManager.cs b/Assets/Scripts/Managers/PetManager.cs
index 3ec028d..64abc8b 100644
--- a/Assets/Scripts/Managers/PetManager.cs
+++ b/Assets/Scripts/Managers/PetManager.cs
@@ -11,6 +11,7 @@ public class PetManager : MonoBehaviour, IDataPersistence
     void Start()
     {
         player = GameObject.FindGameObjectWithTag("Player");
+        DataPersistenceManager.instance.getPlayerName();
     }
 
     public void SpawnPet(string petTag, double petHealth, Vector3 playerPosition)
-- 
GitLab