【问题标题】:Unity 2D: Timer in while loop not working, loop stays foreverUnity 2D:while循环中的计时器不起作用,循环永远存在
【发布时间】:2018-11-26 18:05:25
【问题描述】:

我希望在游戏开始时从 0 开始进行提升工作。

在我的游戏中,我可以捡起助推币来填满我的助推器罐。

public static int boost;

private void OnTriggerEnter2D(Collider2D otherObject)
{
    if (otherObject.tag == "Boost")
    {
        boost++;
        GetComponent<AudioSource>().PlaySound(BoostSound, 5.7F);
        Destroy(otherObject.gameObject);
    }
}

在玩家拾取足够的助推器硬币以在 2d 车辆中使用助推器后。

您至少需要 3 次提升才能启动助推器。每个助推器硬币等于 1 秒的助推器。

我只是希望玩家在收集到超过 3 个助推币时能够使用助推器,如果他们有 3 个或更多代表他们可以使用助推器的秒数。

按钮调用代码

public void BoostButton()
{
  StartCoroutine("Use_VehicleBoost");
}

按钮调用的助推器代码。

IEnumerator Use_VehicleBoost()
{
    //   Check which boost package player picked
    int boostLevel = SecurePlayerPrefs.GetInt("BoostLevel");
    if (boostLevel == 0)
    {
        Debug.Log("Boost Level: None");
        yield return null;
    }
    else if (boostLevel == 1)
    {
        Debug.Log("Boost Level: 1");

        float aceleRate = 400, maxFWD = -2500;
        while (Player.boost >= 3)
        {
            vehicleController.GetComponent<CarMovement>().accelerationRate += aceleRate;
            vehicleController.GetComponent<CarMovement>().maxFwdSpeed += maxFWD;

            //  Meant to slowly take one point/ Time second away from boost tank
            Player.boost = Player.boost - Mathf.RoundToInt(Time.deltaTime);
        }
        if (Player.boost <= 0)
        {
            yield return null;
        }
    }
    yield return null;
}

问题:代码卡在 while 循环中,导致 Unity 冻结。它永远无法逃脱循环,但是如果我在循环运行时使用 deltaTime 调用 --boost 怎么办。

【问题讨论】:

  • yield return null 应该在 while 循环块中。现在,它不是。您可以在while 循环之外和if 语句中使用它。
  • 这是我错过的谢谢。为什么没有yield返回null时while循环不能中断?
  • 因为Player.boost &gt;= 3 始终为真。循环中断必须为假。现在,如果您将while 循环内的Player.boost 更改为false,它会起作用。如果您在 another 脚本中更改 Player.boost,它将无法正常工作,因为其他脚本将永远无法运行更改,因为您的 while 循环。当您向其中添加yield return null 时,它将告诉Unity 在while 循环结束时等待每一帧。在等待每一帧时,其他脚本现在可以运行,因此您的 Player.boost 将有机会被更改.....
  • 啊,所以yield return null 是公开阻止它的原因。所以Player.boost 没有倒计时,while 循环中的Player.boost - Time.deltaTime 怎么倒计时?是不是靠着框架就保不住价值了?
  • 您不会在该循环中更改Player.boost,因此只要while (Player.boost &gt;= 3) 为真,while 循环就会一直运行。这就是导致冻结的原因。 Player.boost 不是 PlayerScripts.boost。要更改它必须是Player.boost = somethingMoreOrEqualsTo3

标签: unity3d


【解决方案1】:

如果您想使用该 while 循环进行检查,请将其用于 IEnumerator 并等待每一帧。例如:

IEnumerator Use_VehicleBoost(){
...
while (Player.boost >= 3)
{
     yield return null;
}
...
}

【讨论】:

  • 还是同样的问题,我用Coroutine 更新了问题,就像你提到的那样。
  • 如果您使用 Coroutine,Unity 无法使用您显示的此代码冻结。
  • 它确实冻结了,可能是因为它仍然卡在 while 循环中
  • 因为你没有增加你的变量 Player.boost >= 3。当它可以通过 3 时,只需仔细检查你的变量。
  • 我不是要增加 Player.boost 。Player 会收集秒数用作提升,直到 0。
【解决方案2】:

我通过在更新中设置一个布尔值来做到这一点,当技能被激活时翻转为真,一旦条件不再满足,翻转为假。当该 bool 翻转为 true 以保持所需行为时,也会调用一个方法。我实际上和你有同样的问题,没有意识到 yield return null 是解决方案,所以这就是我想出的。

    if (ultCharge >= pilotUltMin && !pilotUlting && !pilotUltingPressed)
    {
        if (Input.GetButton(bumperR1))
        {
            pilotUltingPressed = true;
            pilotUlting = true;
            curCharge = ultCharge;
            pilotUltingPressed = false;
        }
    }

    if (pilotUlting)
    {
        PilotUlt();
    }
}

private void PilotUlt()
{
    if (ultCharge > curCharge - pilotUltMax && ultCharge >= 0)
    {
        rb.AddRelativeForce(Vector2.up * SwitchController.ShipSpeed * 1.5f, ForceMode2D.Impulse);
        ultCharge -= 0.7f;
        ultExhaust1.SetActive(true);
        ultExhaust2.SetActive(true);
    }
    else
    {
        pilotUlting = false;
        ultExhaust1.SetActive(false);
        ultExhaust2.SetActive(false);
    }
}

【讨论】:

    猜你喜欢
    • 2014-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    • 2020-08-12
    • 2019-04-05
    相关资源
    最近更新 更多