Dev
Dev

Reputation: 45

How to change a value of an item from another class?

I'm sorry, I just start using Unity 3D, I have no experience with it. I want to add 500 coins whenever the user win in a level, in my code, when the user win, a pop up show up, but I want also add 500 coins to the user.
This is my code:

public class GameScreen : BaseScreen
{
.....
    public void OpenWinPopup()
    {

        OpenPopup<WinPopup>("Popups/WinPopup", popup =>
        {

            var gameState = GameLogic.GameState;
            var levelStars = PlayerPrefs.GetInt("level_stars_" + levelInfo.Number);
            if (gameState.Score >= levelInfo.Star3Score)
            {
                popup.SetStars(3);
                PlayerPrefs.SetInt("level_stars_" + levelInfo.Number, 3);
            }
            else if (gameState.Score >= levelInfo.Star2Score)
            {
                popup.SetStars(2);
                if (levelStars < 3)
                {
                    PlayerPrefs.SetInt("level_stars_" + levelInfo.Number, 2);
                }
            }
            else if (gameState.Score >= levelInfo.Star3Score)
            {
                popup.SetStars(1);
                if (levelStars < 2)
                {
                    PlayerPrefs.SetInt("level_stars_" + levelInfo.Number, 1);
                }
            }
            else
            {
                popup.SetStars(0);
            }

            var levelScore = PlayerPrefs.GetInt("level_score_" + levelInfo.Number);
            if (levelScore < gameState.Score)
            {
                PlayerPrefs.SetInt("level_score_" + levelInfo.Number, gameState.Score);
            }

            popup.SetScore(gameState.Score);
            popup.SetGoals(levelInfo.Goals, gameState, LevelGoalsWidget);
        });
    }
}

This is the class of CoinSystem:

[CreateAssetMenu(fileName = "CoinsSystem", menuName = "MyFirstGame/Systems/Coins system", order = 1)]
public class CoinsSystem : ScriptableObject
{
    private Action<int> onCoinsUpdated;

    public void BuyCoins(int amount)
    {
        var numCoins = PlayerPrefs.GetInt("num_coins");
        numCoins += amount;
        PlayerPrefs.SetInt("num_coins", numCoins);
        onCoinsUpdated?.Invoke(numCoins);
    }

    public void SpendCoins(int amount)
    {
        var numCoins = PlayerPrefs.GetInt("num_coins");
        numCoins -= amount;
        if (numCoins < 0)
            numCoins = 0;
        PlayerPrefs.SetInt("num_coins", numCoins);
        onCoinsUpdated?.Invoke(numCoins);
    }

    public void Subscribe(Action<int> callback)
    {
        onCoinsUpdated += callback;
    }

    public void Unsubscribe(Action<int> callback)
    {
        if (onCoinsUpdated != null)
            onCoinsUpdated -= callback;
    }
}

I spend I lot of time with no result, it's my first time using Unity 3D.

Upvotes: 0

Views: 285

Answers (1)

Applejag
Applejag

Reputation: 1258

If your GameScreen class is derived from MonoBehaviour I suggest adding a public variable pointing to your CoinSystem. Example add this to GameScreen.cs:

public class GameScreen : BaseScreen
{
    // Add this ↓↓
    public CoinsSystem coinsSystem;
}

Then drag'n'drop your CoinsSystem asset from "Project" tab to your GameScreen component property that will be named "Coins System".

After that you can access your CoinsSystem via the coinsSystem variable, as such:

public class GameScreen : BaseScreen
{
    public CoinsSystem coinsSystem;

    public void OpenWinPopup()
    {
        coinsSystem.BuyCoins(500);

        OpenPopup<WinPopup>("Popups/WinPopup", popup =>
        {
            // *Rest of OpenPopup<WinPopup> code*
        });
    }
}

It is however bad habit referring to the serialized value on each value get/set. Recommended usage is via a variable and then have a dedicated Save() and Load() function. Partial example:

public class CoinsSystem : ScriptableObject
{
    private Action<int> onCoinsUpdated;

    public int coins;

    public void BuyCoins(int amount)
    {
        coins += amount;
        onCoinsUpdated?.Invoke(coins);

        // Optionally have this to save on each BuyCoins call:
        // Save()
    }

    public void Save()
    {
        PlayerPrefs.SetInt("num_coins", coins);
    }

    public void Load()
    {
        coins = PlayerPrefs.GetInt("num_coins");
    }
}

Upvotes: 1

Related Questions