简体   繁体   English

如何从另一个类更改项的值?

[英]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. 对不起,我刚开始使用Unity 3D,我对它没有经验。 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. 我希望每当用户在一个关卡中获胜时添加500个硬币,在我的代码中,当用户获胜时,弹出显示,但我还想向用户添加500个硬币。
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 : 这是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. 我花了很多时间没有结果,这是我第一次使用Unity 3D。

If your GameScreen class is derived from MonoBehaviour I suggest adding a public variable pointing to your CoinSystem . 如果您的GameScreen类是从MonoBehaviour派生的,我建议添加一个指向您的CoinSystem的公共变量。 Example add this to GameScreen.cs : 示例将此添加到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". 然后将您的CoinsSystem资产从“项目”选项卡GameScreen到将命名为“硬币系统”的GameScreen组件属性。

After that you can access your CoinsSystem via the coinsSystem variable, as such: 之后,你可以访问你的CoinsSystem通过coinsSystem变量,例如:

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. 然而,在每个值get / set上引用序列化值是坏习惯。 Recommended usage is via a variable and then have a dedicated Save() and Load() function. 建议用法是通过变量,然后使用专用的Save()Load()函数。 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");
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM