Hi there, I’m working on my first game and it’s an RPG with lots of attributes, skills, and items so I decided it was about time to start working on the save/load system last week and after some help from this forum I decided to try JSON utilities for this.
Some things work great (primitive data types), but others have had me pulling my hair out because I can’t seem to get it working, and I can’t find any tutorials/guides that deal with saving anything more complex than primitive data types.
Here is the current situation:
I’m trying to currently save everything having to do with the player (attributes, and inventory mainly). I can save the attributes just fine (strength, dexterity, current health, etc.). All of those are either ints or ScriptableObjects that hold int values.
The issue is with the inventory. My player’s inventory is an SO with List<Item> inventoryList = new List<Item>();
and Item is a public class with a bunch of item properties (name, type, value, etc.).
I can’t for the life of me figure out how to save that list of Items to the JSON file that I was working with.
Here is my SaveLoadManager for saving to JSON:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SaveLoadManager : MonoBehaviour
{
Player player;
private void Awake()
{
player = FindObjectOfType<Player>();
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.H))
{
Save();
}
else if (Input.GetKeyDown(KeyCode.J))
{
Load();
}
}
public void Save()
{
SaveObject saveObject = CreateSaveObject();
foreach (Item item in player.Inventory.InventoryList)
{
Debug.Log("Adding " + item.ItemName + " to save list...");
saveObject.itemList.Add(item);
}
string jsonSave = JsonUtility.ToJson(saveObject);
SaveLoadSystem.SaveData(jsonSave);
}
public void Load()
{
string loadString = SaveLoadSystem.LoadData();
if (loadString != null)
{
SaveObject saveObject = JsonUtility.FromJson<SaveObject>(loadString);
AllocateLoad(saveObject);
Debug.Log("Loaded: " + loadString);
player.PlayerMoney.CalculateMoney();
}
else
{
Debug.Log("No save file to load");
}
}
private SaveObject CreateSaveObject()
{
SaveObject newSaveObject = new SaveObject
{
strength = player.PlayerStats.Strength,
dexterity = player.PlayerStats.Dexterity,
constitution = player.PlayerStats.Constitution,
intelligence = player.PlayerStats.Intelligence,
perception = player.PlayerStats.Perception,
charisma = player.PlayerStats.Charisma,
raceBaseHP = player.PlayerStats.BaseHealth,
currentHP = player.PlayerStats.CurrentPlayerHP.IntVariable,
playerCopper = player.PlayerMoney.Copper,
playerSilver = player.PlayerMoney.Silver,
playerGold = player.PlayerMoney.Gold,
itemList = new List<Item>(),
};
return newSaveObject;
}
private void AllocateLoad(SaveObject saveObject)
{
player.PlayerStats.Strength = saveObject.strength;
player.PlayerStats.Dexterity = saveObject.dexterity;
player.PlayerStats.Constitution = saveObject.constitution;
player.PlayerStats.Intelligence = saveObject.intelligence;
player.PlayerStats.Perception = saveObject.perception;
player.PlayerStats.Charisma = saveObject.charisma;
player.PlayerStats.BaseHealth = saveObject.raceBaseHP;
player.PlayerStats.CurrentPlayerHP.IntVariable = saveObject.currentHP;
player.PlayerMoney.Copper = saveObject.playerCopper;
player.PlayerMoney.Silver = saveObject.playerSilver;
player.PlayerMoney.Gold = saveObject.playerGold;
}
private class SaveObject
{
public int strength;
public int dexterity;
public int constitution;
public int intelligence;
public int perception;
public int charisma;
public int raceBaseHP;
public int currentHP;
public int playerCopper;
public int playerSilver;
public int playerGold;
public List<Item> itemList;
}
}
And here is my SaveLoadSystem code which basically just writes this manager’s work to the file:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public static class SaveLoadSystem
{
private static string SAVE_FOLDER = "I:/Game Dev/PE Saves/";
private static string DATA_PATH = "MyGameSave.sav";
private static string FULL_PATH = SAVE_FOLDER + DATA_PATH;
public static void SaveData(string saveString)
{
if (!Directory.Exists(SAVE_FOLDER))
{
Directory.CreateDirectory(SAVE_FOLDER);
}
Debug.Log("Save Location: " + SAVE_FOLDER);
File.WriteAllText(FULL_PATH, saveString);
Debug.Log("Saved: " + saveString);
}
public static string LoadData()
{
if (File.Exists(FULL_PATH))
{
string loadString = File.ReadAllText(FULL_PATH);
return loadString;
}
else
{
return null;
}
}
}
I’m guessing that what I’m doing is just not an option, and that I need to save the inventory items to the file in a different way, but I don’t know how. Since I have to pass in an object for the JSON utility I need to get all the items in the player’s inventory to save onto that object and I can’t figure out how to do that.
I even tried switching to a binary formatter thinking maybe I could figure that out but nope.
Any helps with this would be greatly appreciated, thanks so much!
EDIT: Was asked to post my Item class so here it is:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[Serializable]
public class Item
{
// Main properties
string itemName = "Item name";
ItemSubType itemSubType;
float weight = 0.0f;
Quality itemQuality;
private bool consumable = false;
// Weapon properties
int minDamage = 10;
int maxDamage = 15;
float attackSpeedBonus = 1f;
WeaponSpeed weaponSpeed;
float range = 2f;
bool ranged = false;
// Armor properties
int armor = 0;
// Potion properties
int healAmount = 0;
int damageAmount = 0;
// Attribute properties
int strength = 0;
int dexterity = 0;
int constitution = 0;
int intelligence = 0;
int perception = 0;
int charisma = 0;
// Modifiers
List<Modifier> modifiers = new List<Modifier>();
// Ownership properties
Owner owner;
bool stolen = false;
// Value properties
int copper = 0;
int silver = 0;
int gold = 0;
float floatCurrency;
int whole;
float remainder;
public void SetItemProperties(Item item)
{
itemName = item.ItemName;
itemSubType = item.ItemSubType;
weight = item.Weight;
itemQuality = item.ItemQuality;
consumable = item.Consumable;
minDamage = item.MinDamage;
maxDamage = item.MaxDamage;
attackSpeedBonus = item.AttackSpeedBonus;
weaponSpeed = item.WeaponSpeed;
range = item.Range;
ranged = item.Ranged;
armor = item.Armor;
healAmount = item.HealAmount;
damageAmount = item.DamageAmount;
modifiers = item.Modifiers;
copper = item.Copper;
silver = item.Silver;
gold = item.Gold;
}
public void CalculateValue(Item item)
{
floatCurrency = (float)item.copper / 100;
whole = (int)Mathf.Floor(floatCurrency);
remainder = item.copper;
remainder = remainder - whole * 100;
item.copper = (int)remainder;
item.silver += whole;
floatCurrency = (float)item.silver / 100;
whole = (int)Mathf.Floor(floatCurrency);
remainder = item.silver;
remainder = remainder - whole * 100;
item.silver = (int)remainder;
item.gold += whole;
}
#region Getters & Setters
public string ItemName
{
get { return itemName; }
set { itemName = value; }
}
public ItemSubType ItemSubType
{
get { return itemSubType; }
set { itemSubType = value; }
}
public float Weight
{
get { return weight; }
set { weight = value; }
}
public Quality ItemQuality
{
get { return itemQuality; }
set { itemQuality = value; }
}
public bool Consumable
{
get { return consumable; }
set { consumable = value; }
}
public int MinDamage
{
get { return minDamage; }
set { minDamage = value; }
}
public int MaxDamage
{
get { return maxDamage; }
set { maxDamage = value; }
}
public float AttackSpeedBonus
{
get { return attackSpeedBonus; }
set { attackSpeedBonus = value; }
}
public WeaponSpeed WeaponSpeed
{
get { return weaponSpeed; }
set { weaponSpeed = value; }
}
public float Range
{
get { return range; }
set { range = value; }
}
public bool Ranged
{
get { return ranged; }
set { ranged = value; }
}
public int Armor
{
get { return armor; }
set { armor = value; }
}
public int HealAmount
{
get { return healAmount; }
set { healAmount = value; }
}
public int DamageAmount
{
get { return damageAmount; }
set { damageAmount = value; }
}
public int Strength
{
get { return strength; }
set { strength = value; }
}
public int Dexterity
{
get { return dexterity; }
set { dexterity = value; }
}
public int Constitution
{
get { return constitution; }
set { constitution = value; }
}
public int Intelligence
{
get { return intelligence; }
set { intelligence = value; }
}
public int Perception
{
get { return perception; }
set { perception = value; }
}
public int Charisma
{
get { return charisma; }
set { charisma = value; }
}
public List<Modifier> Modifiers
{
get { return modifiers; }
set { modifiers = value; }
}
public Owner Owner
{
get { return owner; }
set { owner = value; }
}
public bool Stolen
{
get { return stolen; }
set { stolen = value; }
}
public int Copper
{
get { return copper; }
set { copper = value; }
}
public int Silver
{
get { return silver; }
set { silver = value; }
}
public int Gold
{
get { return gold; }
set { gold = value; }
}
#endregion
}