Unsure how to make my save script to work? (Answerd)

Hello everyone, first time using the forums so bare with me here.

I’m making a small game in Unity v.5.6.3p2 and the base concept is that the player has a inventory on which i store variables such as health, money etc etc.

The error i get is

and i understand the error and all but i’m not sure on how i would solve it and that is why i’m in hope that one of you all can help me.

This is my Inventory Script (Very simple atm but more will be added there later)

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

public class Inventory : MonoBehaviour
{
    private Player _Player;
    public GameObject Player;

    public float Health = 0.0f;
    public int Gold = 0;
    public int Stone = 0;
    public int Wood = 0;
    public int Emerald = 0;
    public int Ruby = 0;
    public int Sapphire = 0;

    private bool IsBuying = false;
    private int PriceOfLandINT;
    public Text myText;

    private void Update() //Checks if player is in buy menu and changes the myText to next message
    {
        IsBuying = Player.GetComponent<Player>().IsBuying;
        if (IsBuying == true)
        {
            PriceOfLandINT = Player.GetComponent<Player>().PriceOfLandINT;

            myText.text = "Current gold : "+ Gold +
                "\n Map cost :"+ PriceOfLandINT;
        }
        else
        {
            UIText();
        }
    }

    public void UIText() //This is always visable unless player is in the buy menu
    {
        myText.text = "Health :" + Health +
    "\n Gold :" + Gold +
    "\n Stone :" + Stone +
    "\n Wood :" + Wood +
    "\n Emerald :" + Emerald +
    "\n Ruby :" + Ruby +
    "\n Sapphire :" + Sapphire +
    "";
    }
}

and here is my Save/load script

using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

    public class GameData
    {
    public static float Health;
    public static int Gold;
    public static int Stone;
    public static int Wood;
    public static int Emerald;
    public static int Ruby;
    public static int Sapphire;
    public static int PriceOfLandInt;
    public static int xp;
    public static int Level;
    public static GameObject[] StartLand;
    public static GameObject[] BuyableMaps;
   
}
public class SaveLoad
{
    private Inventory _Inventory;
    public void Save()
        {
        GameData.Health = _Inventory.Health;
        BinaryFormatter binaryFormatter = new BinaryFormatter();
        using (FileStream fs = new FileStream("gamesave.bin", FileMode.Create, FileAccess.Write))
        {
            binaryFormatter.Serialize(fs, GameData.Health);
            binaryFormatter.Serialize(fs, GameData.Gold);
            binaryFormatter.Serialize(fs, GameData.Stone);
            binaryFormatter.Serialize(fs, GameData.Wood);
            binaryFormatter.Serialize(fs, GameData.Emerald);
            binaryFormatter.Serialize(fs, GameData.Ruby);
            binaryFormatter.Serialize(fs, GameData.Sapphire);
            binaryFormatter.Serialize(fs, GameData.PriceOfLandInt);
            binaryFormatter.Serialize(fs, GameData.xp);
            binaryFormatter.Serialize(fs, GameData.Level);
        }
        }
    public static void Load()
    {
        if(!File.Exists("gamesave.bin"))
        {
            return;
        }
        BinaryFormatter binaryFormatter = new BinaryFormatter();
        using (FileStream fs = new FileStream("gamesave.bin", FileMode.Open, FileAccess.Read))
        {
           GameData.Health = (float)binaryFormatter.Deserialize(fs);
           GameData.Gold = (int)binaryFormatter.Deserialize(fs);
           GameData.Stone = (int)binaryFormatter.Deserialize(fs);
           GameData.Wood = (int)binaryFormatter.Deserialize(fs);
           GameData.Emerald = (int)binaryFormatter.Deserialize(fs);
           GameData.Ruby = (int)binaryFormatter.Deserialize(fs);
           GameData.Sapphire = (int)binaryFormatter.Deserialize(fs);
           GameData.PriceOfLandInt = (int)binaryFormatter.Deserialize(fs);
           GameData.xp = (int)binaryFormatter.Deserialize(fs);
           GameData.Level = (int)binaryFormatter.Deserialize(fs);
        }

    }
}

and this is how i call it ingame (this will also be changed later but im using this to test if it works)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

namespace Assets.Scripts
{
    public class SaveManager : MonoBehaviour
    {
        void Start()
        {
            SaveLoad.Save();
            SaveLoad.Load();
            Debug.Log(GameData.Health);
        }
    }
}

Thanks in advance for any help and im sorry if there is some grammar mistakes. English is not my main language :slight_smile:

Best Regards
Lunix
ps, if you need any more info just ask and i will try to answer it as best as i can :slight_smile:

Not sure why you save/load right away, but maybe for testing :slight_smile:
So, your Load method is static and that can be called without the instance, but your Save is not.
So, either you change it to static or you have to create an instance of SaveLoad before using that variable to call the Save method.

2 Likes

Thanks for the quick respond!
Yes, i call it right after because of testing it and i got it to work with this code :slight_smile:

using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using Assets.Scripts;
    public class GameData
    {
    public static float Health;
    public static int Gold;
    public static int Stone;
    public static int Wood;
    public static int Emerald;
    public static int Ruby;
    public static int Sapphire;
    public static int PriceOfLandInt;
    public static int xp;
    public static int Level;
    public static GameObject[] StartLand;
    public static GameObject[] BuyableMaps;
   
    }
    public class SaveLoad
    {

     public static void Save()
       {
        Inventory inventory = new Inventory();
        GameData.Health = inventory.Health;

        BinaryFormatter binaryFormatter = new BinaryFormatter();
        using (FileStream fs = new FileStream("gamesave.bin", FileMode.Create, FileAccess.Write))
        {
            binaryFormatter.Serialize(fs, GameData.Health);
            binaryFormatter.Serialize(fs, GameData.Gold);
            binaryFormatter.Serialize(fs, GameData.Stone);
            binaryFormatter.Serialize(fs, GameData.Wood);
            binaryFormatter.Serialize(fs, GameData.Emerald);
            binaryFormatter.Serialize(fs, GameData.Ruby);
            binaryFormatter.Serialize(fs, GameData.Sapphire);
            binaryFormatter.Serialize(fs, GameData.PriceOfLandInt);
            binaryFormatter.Serialize(fs, GameData.xp);
            binaryFormatter.Serialize(fs, GameData.Level);
        }
     }
    public static void Load()
    {
        if(!File.Exists("gamesave.bin"))
        {
            return;
        }
        BinaryFormatter binaryFormatter = new BinaryFormatter();
        using (FileStream fs = new FileStream("gamesave.bin", FileMode.Open, FileAccess.Read))
        {
           GameData.Health = (float)binaryFormatter.Deserialize(fs);
           GameData.Gold = (int)binaryFormatter.Deserialize(fs);
           GameData.Stone = (int)binaryFormatter.Deserialize(fs);
           GameData.Wood = (int)binaryFormatter.Deserialize(fs);
           GameData.Emerald = (int)binaryFormatter.Deserialize(fs);
           GameData.Ruby = (int)binaryFormatter.Deserialize(fs);
           GameData.Sapphire = (int)binaryFormatter.Deserialize(fs);
           GameData.PriceOfLandInt = (int)binaryFormatter.Deserialize(fs);
           GameData.xp = (int)binaryFormatter.Deserialize(fs);
           GameData.Level = (int)binaryFormatter.Deserialize(fs);
        }

    }
}

So thanks for the help :slight_smile:

You’re welcome :slight_smile: Glad you got it working. Enjoy your game.

Sorry for maybe asking a new question in this one (dont know if its against the rules or not so sorry if so)

But it doesnt seem to wanna coperate as i want. So when i click save it just wont grab the data from the

Inventory inventory = new Inventory();
        GameData.Health = inventory.Health;

Any clues?

You’re assigning the “Health” value of the new Inventory object to the GameData.Health field. You JUST created the Inventory object, so it’s going to have the default value for Health- assigning that to something makes little sense. Did you mean to put it the other way around?

Btw, if Inventory is a MonoBehaviour, you cannot create it with the “new” keyword and a constructor this way. It needs to be attached to a GameObject in the scene. If you’re meaning to retrieve an existing Inventory component, you’ll have to use GetComponent() on the GameObject it’s attached to, or something.

1 Like

ah alright, ama try work something out tomorrow (late where i live now) and come back if i make it work :slight_smile: Thanks!

Hope it works for ya :slight_smile:

1 Like

Thanks for the help once again!

I just added this in the save() and that fixed it, i should have thought about it earlier :slight_smile:

        GameObject User = GameObject.FindGameObjectWithTag("Player");
        var inventory = User.GetComponent<Inventory>();

Nice :slight_smile: