如何在 Unity 中显示收集的硬币数量而不会溢出(访问另一个脚本)?

How can I display collected amount of coins without overflow (accessing another script) in Unity?

我有两个脚本。 PlayerMove.csSpawner.cs 。 在 PlayerMove.cs 中,我想要一个将文本更改为硬币数量的函数。

void CountCoin()
{
    cointext.text = ": "+ coincount;
    CountCoin();
}

在 Spawner.cs 中,我每次生成硬币时都想增加硬币数量(这是 PlayerMove.cs 的 public 变量)。

IEnumerator StartSpawningCoins ()
    {
        coin.GetComponent<Renderer>().enabled=true;

        yield return new WaitForSeconds(Random.Range(6f, 16f));

        GameObject k = Instantiate(coin);

        // my problem starts here

        GameObject Player = GameObject.Find("PlayerMove");
        PlayerMove playermove = Player.GetComponent<PlayerMove>();
        playermove.coincount++;

        //till here

        float x = Random.Range(min_X,max_X);

        k.transform.position = new Vector2(x, transform.position.y);

        StartCoroutine(StartSpawningCoins());
    }

当我使用这些时,出现堆栈溢出错误。我该如何解决?

问题是在

void CountCoin()
{
    cointext.text = ": "+ coincount;
    CountCoin();
}

你自己调用CountCoin()


如果您想要重复更新,您可以例如使用 Invoke

void CountCoin()
{
    cointext.text = ": "+ coincount;

    // calls this method again after 1 second
    Invoke(nameof(CountCoin), 1f);
}

或直接InvokeRepeating

void Start()
{
    // calls CountCoin every second, the first time after 1 second delay
    InvokeRepeating(nameof(CountCoin), 1f, 1f);
}

为了每秒调用它。

或者干脆完全删除嵌套调用并在 Update 中添加一个以使其在每一帧都被调用

void Update()
{
    CountCoin();
}

这是我宁愿做的:使 coincount 成为 property 并将相应的行为添加到 setter:

private int _coincount;
public int coincount 
{
    get { return _coincount; }
    set 
    { 
        _coincount = value;
        cointext.text = ": "+ value;
    }
}  

所以每次更改 属性 代码都会自动执行


顺便说一句 Find 非常昂贵,应该避免使用。我会将您的代码更改为

private PlayerMove playermove;

IEnumerator StartSpawningCoins ()
{
    // as long as you yield inside this is ok
    while(true)
    {
        // only do find if needed
        if(!player) player = GameObject.Find("PlayerMove");

        // this should probably actually be done in the prefab not via code
        coin.GetComponent<Renderer>().enabled = true;

        yield return new WaitForSeconds(Random.Range(6f, 16f));

        GameObject k = Instantiate(coin);
        playermove.coincount++;

        float x = Random.Range(min_X,max_X);

        k.transform.position = new Vector2(x, transform.position.y);
    }
}