Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Question Saving Items in Dictionary

Discussion in 'Scripting' started by dmarku26, Nov 28, 2022.

  1. dmarku26


    Aug 3, 2020
    Can someone help me with the script below, every time I pick up a new item (for example a key), I can save that in player prefs so that when the player logs out and logs back in, he still has the key. The code works because when I pick up the key it adds it to the inventory but when I restart the game, the key is gone. And I know I need a better system than playerprefs but I want a simple playerpref system for the demo i am building.
    Thank you all. Below is the code. If someone can edit this code so every time i pick up the item, the item is still there after the game restart, that would be great. Same for when the key gets used. It gets removed from the inventory, so that part work, but I want that to be saved in playerprefs, that the item was already consumed/removed.

    Code (CSharp):
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    6. //Manages inventory, and keeps several component references
    8. public class GameManager : MonoBehaviour
    9. {
    10.     public AudioSource audioSource; //A primary audioSource a large portion of game sounds are passed through
    11.     public DialogueBoxController dialogueBoxController;
    12.     public HUD hud; //A reference to the HUD holding your health UI, coins, dialogue, etc.
    13.     public Dictionary<string, Sprite> inventory = new Dictionary<string, Sprite>();
    14.     private static GameManager instance;
    15.     [SerializeField] public AudioTrigger gameMusic;
    16.     [SerializeField] public AudioTrigger gameAmbience;
    18.     // Singleton instantiation
    19.     public static GameManager Instance
    20.     {
    21.         get
    22.         {
    23.             if (instance == null) instance = GameObject.FindObjectOfType<GameManager>();
    24.             return instance;
    25.         }
    26.     }
    28.     // Use this for initialization
    29.     void Start()
    30.     {
    31.         audioSource = GetComponent<AudioSource>();
    32.     }
    34.     // Use this for initialization
    35.     public void GetInventoryItem(string name, Sprite image)
    36.     {
    37.         inventory.Add(name, image);
    39.         if (image != null)
    40.         {
    41.             hud.SetInventoryImage(inventory[name]);
    42.         }
    43.     }
    45.     public void RemoveInventoryItem(string name)
    46.     {
    47.         inventory.Remove(name);
    48.         hud.SetInventoryImage(hud.blankUI);
    49.     }
    51.     public void ClearInventory()
    52.     {
    53.         inventory.Clear();
    54.         hud.SetInventoryImage(hud.blankUI);
    55.     }
    57. }
    Last edited: Nov 28, 2022
  2. Kurt-Dekker


    Mar 16, 2013
    That's not how it works.

    The purpose of this forum is to assist people who are ready to learn by doing, and who are unafraid to get their hands dirty learning how to code, particularly in the context of Unity3D.

    This assumes you have at least written and studied some code and have run into some kind of issue.

    If you haven't even started yet, go check out some Youtube videos for whatever game design you have in mind. There are already many examples of the individual parts and concepts involved, as there is nothing truly new under the sun.

    If you just want someone to do it for you, you need go to one of these places:

    When you are prepared to tackle the problem, here are some relevant notes:

    Load/Save steps:

    An excellent discussion of loading/saving in Unity3D by Xarbrough:

    Loading/Saving ScriptableObjects by a proxy identifier such as name:

    When loading, you can never re-create a MonoBehaviour or ScriptableObject instance directly from JSON. The reason is they are hybrid C# and native engine objects, and when the JSON package calls
    to make one, it cannot make the native engine portion of the object.

    Instead you must first create the MonoBehaviour using AddComponent<T>() on a GameObject instance, or use ScriptableObject.CreateInstance<T>() to make your SO, then use the appropriate JSON "populate object" call to fill in its public fields.

    If you want to use PlayerPrefs to save your game, it's always better to use a JSON-based wrapper such as this one I forked from a fellow named Brett M Johnson on github:

    Do not use the binary formatter/serializer: it is insecure, it cannot be made secure, and it makes debugging very difficult, plus it actually will NOT prevent people from modifying your save data on their computers.

    Here's an example of simple persistent loading/saving values using PlayerPrefs:

    Useful for a relatively small number of simple values.
  3. dmarku26


    Aug 3, 2020
    I understand I used the wrong phrase. I didn't mean for someone to do it for me. I meant someone to point me in the right direction on how to do it with player prefs. If someone can point me in the right direction that would be great. I am able to use both playerprefs or JSON to save things in the game, but as I explained I want just a simple playerpref for this demo phase, but I have tried multiple ways and I can't save the inventory items. And the reason I provided the code was so people can see what I was talking about. I can use playerprefs easily if there is a float or an int, but this specific case is a dictionary item, which takes 2 values at the same time, the item name, and the item sprite. Thank you in advance to anyone who can help me find a way.
  4. Kurt-Dekker


    Mar 16, 2013
    Awesome! That is exactly what I did above already.

    Nothing special about a Dictionary. JSON can serialize those too.

    Once the save data has been collected and serialized into a string, you can save it anywhere you like: playerprefs, a text file, etc.

    It won't be possible for you to complete this task without understanding the steps involved. That's not a thing.
  5. orionsyndrome


    May 4, 2014
    @dmarku26 please fix your code by replacing asterisk (*) on line 6 with a slash (/). it messes up with the rendering of the code, because you've opened a comment block that runs to the end.

    Regarding your question / plea, Kurt said everything relevant there is to say and gave you loads of useful info / tuts / links. I really have nothing to add.
  6. Kurt-Dekker


    Mar 16, 2013
    I just assumed it didn't compile.

    I mean there's really no code there: it's an add, remove and a get on a dictionary and a singleton-ish ctor() pattern, nothing else.

    Oh yeah, it finds an AudioSource but doesn't do anything with it.

    I count a total of 8 SLOC (significant lines of code).

    Maybe it has a kitchen sink too? :)
  7. dmarku26


    Aug 3, 2020
    Thank you I just edited it.
  8. orionsyndrome


    May 4, 2014
    True, it's just a nitpick on my behalf. Simple edit anyway.