- Home /
Problem with saving and loading game timer
HI! I made a Game Time in my inventory that should keep track how long you are playing the game and should counting upwards. I want to save and load this value so that it saves the actual game time and if you load you should start there with the time when you left the game and keep counting from this value upwards. Now is my problem that i cant save and load the value correctly. it starts if i load everytime from 00:00:00. The only thing what get saved is the visuals in the save slot, but there i have also problems because it saves only the float value and not the formatted string value. Maybe anyone can help me?
Here the code:
SaveData.cs
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
[Serializable]
public class SaveData
{
public GameTime MyGameTime { get; set; }
[Serializable]
public class GameTime
{
//public Text MyGameTimeText { get; set; }
public float MyGameTime { get; set; }
public GameTime(float gameTime)
{
MyGameTime = gameTime;
}
}
Then the SaveManager.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SaveManager : MonoBehaviour
{
[SerializeField]
private Item[] items;
private StorageBox[] storageBoxes;
[SerializeField]
private SavedGame[] saveSlots;
private string action;
void Awake()
{
Debug.Log(Application.persistentDataPath);
storageBoxes = FindObjectsOfType<StorageBox>();
foreach (SavedGame saved in saveSlots)
{
//We need to show the saved files here
ShowSavedFiles(saved);
}
//TODO: Set Default values if no saved game is found
}
public void ShowDialogue(GameObject clickButton)
{
action = clickButton.name;
switch (action)
{
case "LoadButton":
Load(clickButton.GetComponentInParent<SavedGame>());
break;
case "SaveButton":
Save(clickButton.GetComponentInParent<SavedGame>());
break;
case "DeleteButton":
Delete(clickButton.GetComponentInParent<SavedGame>());
break;
}
}
private void Delete(SavedGame savedGame)
{
File.Delete(Application.persistentDataPath + "/" + savedGame.gameObject.name + ".dat");
savedGame.HideVisuals();
}
private void ShowSavedFiles(SavedGame savedGame)
{
if (File.Exists(Application.persistentDataPath + "/" + savedGame.gameObject.name + ".dat"))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/" + savedGame.gameObject.name + ".dat", FileMode.Open);
SaveData data = (SaveData)bf.Deserialize(file);
file.Close();
savedGame.ShowInfo(data);
}
}
public void Save(SavedGame savedGame)
{
try
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/" + savedGame.gameObject.name+".dat", FileMode.Create);
SaveData data = new SaveData();
data.MyScene = SceneManager.GetActiveScene().name;
SaveBags(data);
SavePlayer(data);
SaveStorageBoxes(data);
SaveUI(data);
bf.Serialize(file, data);
file.Close();
ShowSavedFiles(savedGame);
}
catch (System.Exception)
{
//This is for handling errors
throw;
}
}
private void SavePlayer(SaveData data)
{
data.MyPlayerData = new PlayerData(Player.MyInstance.MyHealth.MyCurrentValue, Player.MyInstance.MyHealth.MyMaxValue,
Player.MyInstance.transform.position, Player.MyInstance.transform.rotation);
}
private void SaveStorageBoxes(SaveData data)
{
for (int i = 0; i < storageBoxes.Length; i++)
{
data.MyStorageBoxData.Add(new StorageBoxData(storageBoxes[i].name));
foreach (Item item in storageBoxes[i].MyItems)
{
if (storageBoxes[i].MyItems.Count > 0)
{
data.MyStorageBoxData[i].MyItems.Add(new ItemData(item.MyItemName, item.MySlotScript.MyItems.Count, item.MySlotScript.MyIndex));
}
}
}
}
private void SaveBags(SaveData data)
{
for (int i = 1; i < InventoryScript.MyInstance.MyBags.Count; i++)
{
data.MyInventoryData.MyBags.Add(new BagData(InventoryScript.MyInstance.MyBags[i].MySlotCount, InventoryScript.MyInstance.MyBags[i].MyBagButton.MyBagIndex));
}
}
///THATS THE IMPORTANT PART
private void SaveUI(SaveData data)
{
data.MyGameTime = new GameTime(UIManager.MyInstance.MyGameTime);
}
private void Load(SavedGame savedGame)
{
try
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/" + savedGame.gameObject.name + ".dat", FileMode.Open);
SaveData data = (SaveData)bf.Deserialize(file);
file.Close();
LoadBags(data);
LoadPlayer(data);
LoadStorageBoxes(data);
LoadUI(data);
}
catch (System.Exception)
{
//This is for handling errors
throw;
}
}
private void LoadPlayer(SaveData data)
{
Player.MyInstance.MyHealth.Initialize(data.MyPlayerData.MyHealth, data.MyPlayerData.MyMaxHealth);
Player.MyInstance.transform.position = new Vector3(data.MyPlayerData.MyX, data.MyPlayerData.MyY, data.MyPlayerData.MyZ);
Player.MyInstance.transform.rotation = new Quaternion(data.MyPlayerData.MyXRot, data.MyPlayerData.MyYRot, data.MyPlayerData.MyZRot, data.MyPlayerData.MyWRot);
}
private void LoadStorageBoxes(SaveData data)
{
foreach (StorageBoxData storageBox in data.MyStorageBoxData)
{
StorageBox sb = Array.Find(storageBoxes, x => x.name == storageBox.MyName);
foreach (ItemData itemData in storageBox.MyItems)
{
Item item = Array.Find(items, x => x.MyItemName == itemData.MyTitle);
item.MySlotScript = sb.MyBag.MySlots.Find(x => x.MyIndex == itemData.MySlotIndex);
sb.MyItems.Add(item);
}
}
}
public void LoadBags(SaveData data)
{
foreach (BagData bagData in data.MyInventoryData.MyBags)
{
Bag newBag = (Bag)Instantiate(items[0]);
newBag.Initialize(bagData.MySlotCount);
InventoryScript.MyInstance.AddBag(newBag, bagData.MySlotIndex);
}
}
///THATS THE IMPORTANT PART
private void LoadUI(SaveData data)
{
data.MyGameTime = new GameTime(UIManager.MyInstance.MyGameTime);
}
}
SavedGame.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SavedGame : MonoBehaviour
{
[SerializeField]
private Text dateTime;
[SerializeField]
private Text gameTime;
[SerializeField]
private GameObject visuals;
[SerializeField]
private int index;
public int MyIndex
{
get
{
return index;
}
}
private void Awake()
{
visuals.SetActive(false);
}
public void ShowInfo(SaveData saveData)
{
visuals.SetActive(true);
dateTime.text = "Date: " + saveData.MyDateTime.ToString("dd/MM/yyyy") + " - Time: " + saveData.MyDateTime.ToString("H:mm");
gameTime.text = "Game Time: " + saveData.MyGameTime.MyGameTime.ToString();
}
public void HideVisuals()
{
visuals.SetActive(false);
}
}
And finally the UIManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIManager : MonoBehaviour
{
private static UIManager instance;
public static UIManager MyInstance
{
get
{
if (instance == null)
{
instance = FindObjectOfType<UIManager>();
}
return instance;
}
}
public Text MyGameTimeText
{
get
{
return gameTimeText;
}
set
{
gameTimeText = value;
}
}
public float MyGameTime
{
get
{
return gameTime;
}
set
{
gameTime = value;
}
}
public string MyGameTimeString
{
get
{
return gameTimeString;
}
set
{
gameTimeString = value;
}
}
//INVENTORY RELATED
[Header("Inventory UI Settings")]
public CanvasGroup inventory;
[SerializeField]
public SlotScript slotPrefab;
//TOOLTIP RELATED
[Header("Inventory Items Tooltip Settings")]
[SerializeField]
private GameObject tooltip;
[SerializeField]
private Text tooltipTitle;
[SerializeField]
private Text tooltipDescription;
//EXAMINE SYSTEM RELATED
[Header("Examining UI Settings")]
[SerializeField]
private GameObject examineUI;
[Header("Item Menu UI")]
public GameObject buttonMenu;
[SerializeField]
private Text gameTimeText;
private float gameTime = 0f;
private string gameTimeString;
//FUNCTIONS
private void Awake()
{
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
MyGameTime += Time.deltaTime;
int seconds = (int)(MyGameTime % 60);
int minutes = (int)(MyGameTime / 60) % 60;
int hours = (int)(MyGameTime / 3600) % 24;
MyGameTimeString = string.Format("{0:00}:{1:00}:{2:00}", hours, minutes, seconds);
MyGameTimeText.text = "Game Time: " + MyGameTimeString;
if (Input.GetKeyDown(KeyCode.I))
{
OpenClose(inventory);
}
}
//ITEM STACKSIZE
public void UpdateStackSize(IClickable clickable)
{
if (clickable.MyCount > 1)
{
clickable.MyStackText.text = clickable.MyCount.ToString();
clickable.MyStackText.color = Color.white;
clickable.MyIcon.color = Color.white;
}
else
{
clickable.MyStackText.color = new Color(0, 0, 0, 0);
clickable.MyIcon.color = Color.white;
}
if (clickable.MyCount == 0)
{
clickable.MyIcon.color = new Color(0, 0, 0, 0);
clickable.MyStackText.color = new Color(0, 0, 0, 0);
}
}
//ITEM TOOLTIPS
public void ShowTooltip(IDescribable description)
{
tooltip.SetActive(true);
tooltipTitle.text = description.GetName();
tooltipDescription.text = description.GetDescription();
}
public void HideTooltip()
{
tooltip.SetActive(false);
}
//SHOW/HIDE Inventory
public void OpenClose(CanvasGroup canvasGroup)
{
canvasGroup.alpha = canvasGroup.alpha > 0 ? 0 : 1;
canvasGroup.blocksRaycasts = canvasGroup.blocksRaycasts == true ? false : true;
if (!canvasGroup.blocksRaycasts)
{
canvasGroup.blocksRaycasts = true;
}
}
//NEED TO CHANGE!!
public void Test(IDescribable iName)
{
slotPrefab.itemName.text = iName.GetName();
}
//EXAMINE UI
public void ShowExamineUI()
{
examineUI.SetActive(true);
}
public void HideExamineUI()
{
examineUI.SetActive(false);
}
//ITEM BUTTON MENU
public void ShowItemButtonMenu()
{
buttonMenu.SetActive(true);
}
public void HideItemButtonMenu()
{
buttonMenu.SetActive(false);
}
}
Any tips how to save and load the game time in the correct format? Am i missing something? I dont know exatly how to save and load the float value correctly and save and load it as a string in a given format and push it back to the text element. Thanks for help!
Your answer
Follow this Question
Related Questions
How do I make a basic easy Save and load function with JavaScript 1 Answer
Save and load system not working please help 1 Answer
Saving Melee Combat Template Pack (MY LAST PROBLEM) 1 Answer
Saving and loading game with PlayerPrefs 1 Answer
SerializationException: Type UnityEngine.Vector3 is not marked as Serializable. 1 Answer