Search code examples
c#unity-game-enginesaveload

Save a list of shop Items and load it in unity


On the below script im trying to save the ShopItemList everytime I purchase a character that happens OnShopItemBtnClicked function. I am trying to save this with playerprefs but failed. Is there a better way. I heard json is a method we can achieve this. But i dont know what json or how to use this. Can someone help me how to save and load stuff with the current shop system I have. Please I broke my head so much thinking about it dint get an answer

Updated Code

[Serializable]
public class ShopItem
{
    public Sprite CharacterImage;
    public GameObject charactersModel;
    public int Price;
    public bool isPurchased = false;
}

//
[Serializable]
public class ShopDataList
{
    public ShopItem[] ShopItemData;
}

public class Shop : MonoBehaviour
{
    ShopDataList myShopDataList = new ShopDataList();
    //public List<ShopItem> ShopItemsList;


    [Space]
    [Header("Item Template & Display")]
    GameObject ItemTemplate;
    GameObject g;
    [SerializeField] Transform ShopScrollView;
    Button buyBtn;


    GameObject getGameManager;
    GameManager GameManagerRef;



    public void SaveMyData(ShopDataList data)
    {
        string jsonString = JsonUtility.ToJson(data); // this will give you the json (i.e serialize the data)
        File.WriteAllText(Application.dataPath + "/ShopItems.json", jsonString); // this will write the json to the specified path
    }

    public ShopDataList LoadMyData(string pathToDataFile)
    {
        if (!File.Exists(pathToDataFile)) return null;

        string jsonString = File.ReadAllText(pathToDataFile); // read the json file from the file system
        ShopDataList myData = JsonUtility.FromJson<ShopDataList>(jsonString); // de-serialize the data to your myData object
        return myData;
    }

    private void Start()
    {
        LoadMyData(Application.dataPath + "/ShopItems.json");

    getGameManager = GameObject.Find("GameManager");
        GameManagerRef = getGameManager.GetComponent<GameManager>();
        ItemTemplate = ShopScrollView.GetChild(0).gameObject;

        var length = myShopDataList.ShopItemData.Length;
        for (int i = 0; i < length; i++)
        {
            g = Instantiate(ItemTemplate, ShopScrollView);
            g.transform.GetChild(0).GetComponent<Image>().sprite = myShopDataList.ShopItemData[i].CharacterImage; //ShopItemsList[i].CharacterImage; //
            g.transform.GetChild(1).GetComponentInChildren<TextMeshProUGUI>().text = myShopDataList.ShopItemData[i].Price.ToString(); //ShopItemsList[i].Price.ToString(); //**
            buyBtn = g.transform.GetChild(2).GetComponent<Button>();
            if (myShopDataList.ShopItemData[i].isPurchased)
            {
                DisableBuyButton();
            }
            buyBtn.AddEventListener(i, OnShopItemBtnClicked);
        }
        Destroy(ItemTemplate);
    }

    public void DisableBuyButton()
    {
        buyBtn.interactable = false;
        buyBtn.transform.GetChild(0).GetComponent<TextMeshProUGUI>().text = "PURCHASED";

    }



    void OnShopItemBtnClicked(int itemIndex)
    {
        if (GameManagerRef.HasEnoughCoins(myShopDataList.ShopItemData[itemIndex].Price))
        {
            //purchase Item
            GameManagerRef.UseCoins(myShopDataList.ShopItemData[itemIndex].Price);
            myShopDataList.ShopItemData[itemIndex].isPurchased = true;
            buyBtn = ShopScrollView.GetChild(itemIndex).GetChild(2).GetComponent<Button>();
            GameManagerRef.character.Add(myShopDataList.ShopItemData[itemIndex].charactersModel);
            DisableBuyButton();
            SaveMyData(myShopDataList);
        }
        else
        {
            Debug.Log("You dont have sufficient amount");
        }
    }
}

Solution

  • You need to call PlayerPrefs.Save() method to actually save the stuff you've changed in PlayerPrefs.

    But you are right, saving things in an external file is usually a better way to handle it. Json is just a text file with a specific syntax. To save some data to Json first you will have to create a class that will hold the data, like

    [Serializable]
    public class MyData
    {
        public int level;
        public string charName;
    }
    

    The "Serializable" attribute is important because we will need to "Serialize" this data. Unity have a simple json serializer you can use. Here is what you will have to do:

    public void SaveMyData(MyData data)
    {
        string jsonString = JsonUtility.ToJson(data); // this will give you the json (i.e serialize the data)
        File.WriteAllText("Path/file/name.json", jsonString); // this will write the json to the specified path
    }
    
    public MyData LoadMyData(string pathToDataFile)
    {
        string jsonString = File.ReadAllText(pathToDataFile); // read the json file from the file system
        MyData myData = JsonUtility.FromJson<MyData>(jsonString); // de-serialize the data to your myData object
        return myData;
    }
    

    this is what your json file will look like:

    {
        "level":123,
        "charName":"My awesome character"
    }