1

I am creating inventory system for my game and problem is that i need to create system to store multiple values to my device.

I know there are PlayerPrefs but with that i can only store 2 values (let's say key for one and value for second), but i need something like table. So i have to store something like this in single line:

inventorySlot
itemID
amount

this is simple 3 size value, but also i would need to store 4, 5, or more.

So how can i achieve this?

Here is current code where problem is that storing to json is not working. Look at comment at the end of Debug.Log to see what it displays.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class InventoryModel
{
    public List<InventoryItem> InventoryItems;

    public InventoryModel()
    {
        InventoryItems = new List<InventoryItem>();
    }
}

public class InventoryItem
{
    public int inventorySlot;
    public int itemID;
    public float amount;
}


public class Inventory : MonoBehaviour
{
    private int inventorySlots = 5;

    public Text itemSlot1;

    void Start ()
    {
        AddItemToInventory(1, 0, 2000);
        LoadInventory();
    }

    void Update ()
    {

    }

    public static void AddItemToInventory(int slot, int itemID, float amount)
    {
        InventoryModel im = new InventoryModel();
        InventoryItem ii = new InventoryItem();
        ii.inventorySlot = slot;
        ii.itemID = itemID;
        ii.amount = amount;

        im.InventoryItems.Add(ii);

        foreach(InventoryItem ia in im.InventoryItems)
        {
            Debug.Log(ia.itemID + "-" + ia.amount + "-" + ia.inventorySlot);    //Display 0-2000-1
        }
        string jsonString = JsonUtility.ToJson(im);
        Debug.Log(jsonString);                                                  //Display {}
        PlayerPrefs.SetString("PlayerInventory", jsonString);
    }

    private void LoadInventory()
    {
        foreach(InventoryItem ii in LoadInventoryFromPref().InventoryItems)
        {
            //Doesnt enter this loop
            Debug.Log(ii.inventorySlot);
            Debug.Log(ii.itemID);
            Debug.Log(ii.amount);
            Debug.Log("====");
        }
    }

    private static InventoryModel LoadInventoryFromPref()
    {
        string test = PlayerPrefs.GetString("PlayerInventory");
        Debug.Log(test);                                                        //display {}
        return JsonUtility.FromJson<InventoryModel>(test);
    }

    private static int GetMaxInventorySlots()
    {
        if(PlayerPrefs.HasKey("MIS"))
        {
            return PlayerPrefs.GetInt("MIS");
        }
        else
        {
            return 0;
        }
    }
}
Aleksa Ristic
  • 2,394
  • 3
  • 23
  • 54

2 Answers2

2

A similar answer was provided here What is the best way to save game state? that uses DataSaver.saveData.

Use PlayerPrefs to store a JSON instead of individual keys. As long as the data is less than 1MB in size, PlayerPrefs is the best option.

Since all you wish to store is an array of:

inventorySlot
itemID
amount

You can do the following:

{
  "Items": [
    {
      "inventorySlot": 1,
      "itemID": "123ABC",
      "amount": 234
    },
    {
      "inventorySlot": 2,
      "itemID": "123ABC",
      "amount": "554"
    }
  ]
}

Then store that in PlayerPref by assigning it to a key of your choice using setString

You can then utilize Unity's JsonUtility to serialize/deserialize the JSON.

The Model (Note: Decorate models with [System.Serializable]:

[System.Serializable]
public class InventoryModel
{
    public List<Item> Items = new List<Item>();
}

[System.Serializable]
public class Item
{
    public int inventorySlot;
    public string itemID;
    public int amount;
}

Here's a full example:

    InventoryModel invModel = new InventoryModel();

    Item model = new Item();
    model.inventorySlot = 1;
    model.itemID = "123ABC";
    model.amount = 234;

    Item model2 = new Item();
    model2.inventorySlot = 2;
    model2.itemID = "123ABC";
    model2.amount = 554;

    invModel.Items.Add(model);
    invModel.Items.Add(model2);

    //Generate JSON then save it
    string yourModelJson = JsonUtility.ToJson(invModel);
    PlayerPrefs.SetString("InventoryKey", yourModelJson);

   //Read JSON back to Model
   InventoryModel testModel = new InventoryModel();
   string rawJsonFromPref = PlayerPrefs.GetString("InventoryKey");
   testModel = JsonUtility.FromJson<InventoryModel>(rawJsonFromPref);
Dayan
  • 7,634
  • 11
  • 49
  • 76
  • @Downvoter When you downvote, add a comment so that we know why there was a downvote. It helps me improve the answer. – Dayan Jun 30 '17 at 18:52
  • I do not know why anyone downvote anything since here you are getting free advices. Anyway it looks totaly ok to me and i will try it tomorrow. I didn't know about JSON so i will tell you tomorrow hwo it was – Aleksa Ristic Jun 30 '17 at 19:00
  • Not me but why do people feel the need to answer a duplicate? I mean this question has been asked many times and you should know that by doing a quick search. Also, remove `{get; set;}`. That wouldn't work. – Programmer Jun 30 '17 at 19:02
  • @Programmer Thanks, I fixed the `{get;set;}`, the question marked as duplicate uses a different approach though - `DataSaver.saveData` instead of what my answer covers `PlayerPref.SetString`. I will include that answer 's url in mine for reference. – Dayan Jun 30 '17 at 19:07
  • Both questions are asking the-same thing. That answer mentioned `PlayerPrefs` twice and provided a link for another solution that uses that. It did not use `PlayerPrefs` on purpose but instead used `File.WriteAllBytes`. It's the-same process....Convert to Json then save. – Programmer Jun 30 '17 at 19:10
  • @Programmer Fair enough, would it best for me to delete this answer then? – Dayan Jun 30 '17 at 19:11
  • 1
    You don't have to. You may have to do a quick search before adding answers. It looks like the downvote is out so I put an upvote. – Programmer Jun 30 '17 at 20:08
  • 1
    @Programmer I will make sure to do that, thanks again. – Dayan Jun 30 '17 at 20:17
  • @Dayan for some reason it gives me null error at `JsonUtility.ToJson`. Here is my [code](https://pastebin.com/4x4XFdQX) – Aleksa Ristic Jul 01 '17 at 18:23
  • when i print ii it has values but for some reason inventory model is not adding it – Aleksa Ristic Jul 01 '17 at 18:24
  • Fount out, i should have initialized `InventoryItem` list inside `InventoryModel` – Aleksa Ristic Jul 01 '17 at 18:41
  • But still for some reason i can not read it :/ – Aleksa Ristic Jul 01 '17 at 18:41
  • @AleksaRistic Updated the answer, see if it helps read the saved data. If not, let me know if you encounter an exception. Use `Debug.log` to see the data from the object and such. – Dayan Jul 01 '17 at 19:21
  • When i print json string before i store it to pref it print `{}` and i guess that is empty? – Aleksa Ristic Jul 02 '17 at 08:50
  • But when i print `itemmodel` it has values, it is like converting into json string is not working – Aleksa Ristic Jul 02 '17 at 08:51
  • @AleksaRistic When you execute `toJson` does it output the correct JSON? If so, after you save it, and retrieve it does it still show the same JSON? – Dayan Jul 02 '17 at 09:01
  • Look at edited question, i added whole class so you can see what have i done and after `Debug.Log` you have comments on what it displays – Aleksa Ristic Jul 02 '17 at 09:14
  • @AleksaRistic You must decorate your model with `[System.Serializable]` that's why it's not serializing/deserializing. Take a look at the example I added in the answer, it has the decorator. – Dayan Jul 02 '17 at 09:20
  • ... Thanks I haven't read about it that much and forgot that problem may be for that. Thanks so much :) – Aleksa Ristic Jul 02 '17 at 09:22
  • @AleksaRistic Anytime, glad to help! GL with your game. – Dayan Jul 02 '17 at 09:23
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/148158/discussion-between-aleksa-ristic-and-dayan). – Aleksa Ristic Jul 02 '17 at 09:55
0

Try to use sqlite then you do not need to worry about how much data you store.