1

I'm trying to create a shop in another scene. You can access it anytime while playing by pressing H. My problem is that the coins that the player has collected doesn't get saved. I've been trying to search for answers but nothing seems to help.

The Codes: My Global Code that I use to save varibles:

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

public class Global : MonoBehaviour
{
    public static Global Instance;

    public int sumCoins;

    void Awake(){
        if (Instance == null){
            DontDestroyOnLoad(gameObject);
            Instance = this;
        } else if (Instance != this){
            Destroy(gameObject);
        }
    }
}

The code I use to buy items:

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

public class Shop : MonoBehaviour
{
    public Button milk;
    

    void Start()
    {

        Debug.Log("you have " + Global.Instance.sumCoins);
        milk.onClick.AddListener(AddMilk);   
    }

    void AddMilk(){
        Debug.Log("You bought milk");
        //if player has more than 5 coins.
            //add milk
        //else if player has less than 5 coins
            //display "You cant buy this"
        //else if player doesnt have a slot available 
            //display "You cant buy this"
    }
}

The code that's used for counting and adding coins:

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

public class Coinsystem : MonoBehaviour
{
    public int sumCoins = 0;
    private int addedCoins;
    int coins;
    Text txt;
    public GameObject count;
    

    public void Start(){
        Debug.Log("coin system working");
        txt = count.GetComponent<Text>();
        txt.text = "" + sumCoins;
        sumCoins = Global.Instance.sumCoins;
    }

    public void Update(){
       txt.text = "" + sumCoins;
    }

    public void AddCoins(int addedCoins){
        sumCoins += addedCoins;
        Debug.Log("Coins Added!");
    }

    public void SaveMoney(){
        Global.Instance.sumCoins = sumCoins;
    }

}

Thank you for taking your time to read this!

Ce Feline
  • 11
  • 1
  • Does this answer your question? [How to pass data between scenes in Unity](https://stackoverflow.com/questions/32306704/how-to-pass-data-between-scenes-in-unity) – Pac0 Feb 13 '21 at 13:46
  • I might have to add that when switching to the shop scene, the load mode is additive. Do you think that may be the cause of the problem? since you don't actually leave the level when entering the shop – Ce Feline Feb 13 '21 at 14:35

1 Answers1

0

A quick way of solving this problem would be to use a static class. I have sometimes used this method to persist data throughout the application life span.

public static class GameData {

   private static int coins = 0;

   public static void SetCoins(int coinsIn)
   {
      coins = coinsIn;
   }

   public static void AddCoins(int coinsIn)
   {
      coins += coinsIn;
   }

   public static int GetCoins()
   {
      return coins;
   }
}

Then you can just call the methods like this:

GameData.SetCoins(...);

GameData.AddCoins(...);

var coins = GameData.GetCoins();

The other way people solve this problem is as follows:

  • Save/Load to and from local storage (This can be used in conjunction with the class above or used on it's own).
  • PlayerPrefs, similar to using a static class. Find out more about that here.
  • Creating an object with a script attached that uses DontDestroyOnLoad. Find out more about that here.

I wouldn't normally recommend the use of static classes because it is generally bad programming practice but sometimes it is required to get around limitations like this.

Generally, as a rule of thumb, if you are going to use a static class there is usually a better way of doing it.

I would probably say the most preferred way would be to Save/Load the data to and from local storage as and when needed but this approach is a bit too much for what you want to do.

RStevoUK
  • 436
  • 4
  • 10
  • Creating Getters/Setters is no different to typing { get; set; }. There's 4 different ways you could Get/Set that I can think of right now but the way I have done it makes absolutely no difference so that argument isn't even an argument, it's a matter of preference. I agree with the "this" keyword being used because it's not actually an instance of an object but I typed this out in browser and overlooked that small detail. In response the similar post comment, I checked that link at the time and only seen the first answer but I see the second answer explains everything I have explained here. – RStevoUK Feb 14 '21 at 10:48