Search Unity

Question Saving Items in Dictionary

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

  1. dmarku26

    dmarku26

    Joined:
    Aug 3, 2020
    Posts:
    23
    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):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. //Manages inventory, and keeps several component references
    7.  
    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;
    17.  
    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.     }
    27.  
    28.     // Use this for initialization
    29.     void Start()
    30.     {
    31.         audioSource = GetComponent<AudioSource>();
    32.     }
    33.  
    34.     // Use this for initialization
    35.     public void GetInventoryItem(string name, Sprite image)
    36.     {
    37.         inventory.Add(name, image);
    38.  
    39.         if (image != null)
    40.         {
    41.             hud.SetInventoryImage(inventory[name]);
    42.         }
    43.     }
    44.  
    45.     public void RemoveInventoryItem(string name)
    46.     {
    47.         inventory.Remove(name);
    48.         hud.SetInventoryImage(hud.blankUI);
    49.     }
    50.  
    51.     public void ClearInventory()
    52.     {
    53.         inventory.Clear();
    54.         hud.SetInventoryImage(hud.blankUI);
    55.     }
    56.  
    57. }
     
    Last edited: Nov 28, 2022
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    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:

    https://forum.unity.com/forums/commercial-job-offering.49/

    https://forum.unity.com/forums/non-commercial-collaboration.17/

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

    Load/Save steps:

    https://forum.unity.com/threads/save-system-questions.930366/#post-6087384

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

    https://forum.unity.com/threads/save-system.1232301/#post-7872586

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

    https://forum.unity.com/threads/use...lds-in-editor-and-build.1327059/#post-8394573

    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
    new
    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:

    https://gist.github.com/kurtdekker/7db0500da01c3eb2a7ac8040198ce7f6

    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.

    https://docs.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-security-guide

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

    https://gist.github.com/kurtdekker/01da815d2dfd336a925ae38019c3a163

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

    dmarku26

    Joined:
    Aug 3, 2020
    Posts:
    23
    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

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    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

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,104
    @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

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    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

    dmarku26

    Joined:
    Aug 3, 2020
    Posts:
    23
    Thank you I just edited it.
     
  8. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,104
    True, it's just a nitpick on my behalf. Simple edit anyway.