Game Shop

i have the following script, how can i substract score and unlock each level ?
for example level 2 costs 2000 scores.

this is my code. any help is appreciated.
thanks.

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

public class ShopScript : MonoBehaviour
{
    public static int money;
    public Text GameScoreText;
    public Image[] LevelLockedImages;
    public Image[] LevelThumbnailImages;
    public int[] LevelPrices;
    public static bool[] ShopLevelBought = new bool[4];


     void Update()
    {
        GameScoreText.text = money.ToString();

    }

    public void Level02ButtonClick()
    {

        if(money >= 15)
            SceneManager.LoadScene(3); 

    }

    public void Level03ButtonClick()
    {


        SceneManager.LoadScene(4); 

    }

First I would get rid of the text set in Update. Only update Gui when you need to, which is rarely every frame.

Next, you shouldn’t need a separate method for each button click. In this case, a single method with a switch/if statement that checks your money amount and loads the appropriate level should be enough.

1 Like

You could also check on game over, that is if you have one, to see if the player has reached 2000 points. And then use an if variable to react. If score is equal or greater than 2000 then let’s set the next level true. And as brannan said, no need to update. You’re using alot of draw there

1 Like

You can make this code a lot cleaner.
All of your arrays that deal with the attributes of a level can be grouped into a Level object as attributes:

//System.Serializable allows the class attributes to be set from the inspector.
[System.Serializable]
public class Level {
   public Image lockedImage;
   public Image thumbnailImage;
   public int price;
   public bool purchased;
}

And then define a single array of Level objects instead of multiple arrays for each of these attributes:

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

public class ShopScript : MonoBehaviour {
   public static int money;
   public Text GameScoreText;
   public Level[] levels;
}

//System.Serializable allows the class attributes to be set from the inspector.
[System.Serializable]
public class Level {
   public Image lockedImage;
   public Image thumbnailImage;
   public int price;
   public bool purchased;
}

Next, as already pointed out, you shouldn’t create a different method for each button click. Have each button call the same method, but specify some kind of ID as a parameter to use as the index for the Level array when getting/setting attributes:

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

public class ShopScript : MonoBehaviour {
   public static int money;
   public Text GameScoreText;
   public Level[] levels;

   public void LevelButtonClick(int levelID) {
      Level selectedLevel = levels[levelID];

      if(money >= selectedLevel.price) {
         money -= selectedLevel.price;
         selectedLevel.purchased = true;
         SceneManager.LoadScene(levelID);
      }
   }
}

//System.Serializable allows the class attributes to be set from the inspector.
[System.Serializable]
public class Level {
   public Image lockedImage;
   public Image thumbnailImage;
   public int price;
   public bool purchased;
}
2 Likes

Case variables are also a good method.

the problem is if i dont use Update() for showing current score , then when i come from game play scene back to menu scene at any time , then i cannot see current score and score text is not showing updated amount of scores.
for this reason i use Update() .
But if you know more efficient way , please help me woth that too. here are my game play scripts and the way i try to save score in my game . thanks in advance .

get score each time player clicks:

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

public class PlayerInput : MonoBehaviour
{
    public static PlayerInput instance;
    private int overallScore;
    public Text OverallScore;

    private void Awake()
    {
        if (instance != null)
        {
            Destroy (this);
            return;
        }
        instance = this;
    }

    public void OnItemClicked(GameObject Item)
    {
        if (Item.GetComponent<InteractableObj> ().CanBeUsed)
        {
            Item.GetComponent<Animator> ().SetBool ("returning", true);
            Item.GetComponent<Animator> ().SetBool ("Smashing", false);
            Item.GetComponent<InteractableObj> ().isUsed = false;
            Item.GetComponent<InteractableObj> ().ShowBar (false);
            Item.GetComponent<InteractableObj> ().CanBeUsed = false;
            overallScore++;
            ShopScript.money++;
            persistentData.Save();
        }
    }

    void Update ()
    {
        OverallScore.text = overallScore.ToString ();
    }
}

permanent score save system:

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

public class persistentData : MonoBehaviour
{
    public bool autoLoad;
    public bool autoSave;

    void Start()
    {
        if (autoLoad) { Load(); }
        if (autoSave) { Save(); }
    }
    public static void Save()
    {
        BinaryFormatter binaryFormatter = new BinaryFormatter();
        FileStream fileStream = File.Create(Application.persistentDataPath + "/playerInfo.dat");
        PlayerData playerData = new PlayerData();

        playerData.money = ShopScript.money;
        playerData.levelsBought = ShopScript.ShopLevelBought;

        binaryFormatter.Serialize(fileStream, playerData);
        fileStream.Close();
    }
    public static void Load()
    {
        if (File.Exists(Application.persistentDataPath + "/playerInfo.dat")) {
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            FileStream fileStream = File.Open(Application.persistentDataPath + "/playerInfo.dat", FileMode.Open);
            PlayerData playerData = (PlayerData)binaryFormatter.Deserialize(fileStream);
            fileStream.Close();

            ShopScript.money = playerData.money;
            ShopScript.ShopLevelBought = playerData.levelsBought;
        }
    }
}

    [Serializable]
    class PlayerData
    {
        public int money;
        public bool[] levelsBought;
    }

shop script for unlocking new levels with score :

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

public class ShopScript : MonoBehaviour
{
    public static int money;
    public Text GameScoreText;
    public Level[] levels;

    public void LevelButtonClick(int levelID)
    {
        Level selectedLevel = levels[levelID];

        if(money >= selectedLevel.price)
        {
            money -= selectedLevel.price;
            selectedLevel.purchased = true;
            SceneManager.LoadScene(levelID);
        }
    }
}

//System.Serializable allows the class attributes to be set from the inspector.
[System.Serializable]
public class Level {
    public Image lockedImage;
    public Image thumbnailImage;
    public int price;
    public bool purchased;
}

You should use Start/Awake to do your initial score text update when you switch scenes. Then only update score when the money value changes(have a method you can call to update the text).

2 Likes

can you give me a snippet code?