为了账号安全,请及时绑定邮箱和手机立即绑定

我的倒数计时器卡住了,游戏没有停止

我的倒数计时器卡住了,游戏没有停止

C#
月关宝盒 2021-11-14 10:20:52
我正在尝试创建一个倒计时计时器,以便我的玩家在游戏再次开始玩之前购买第二条生命 3 秒。我不确定我需要在下面修复什么才能使其正常工作。目前,所有用户界面都会在应有的时候弹出,倒数计时器文本也会弹出,但游戏继续进行,计时器停留在 3。public static bool GameOver = false;public static bool CountDown = false;public GameObject deathMenuUI;public GameObject countDownUI;public int timeLeft = 3;public Text countDownText;public float slowness = 10f;public void Start(){    PlayerPrefs.SetInt("Score", 0);    Time.timeScale = 1f;}public void EndGame(){    StartCoroutine(DeathScreen());}//on death, slow time for one second and open deathscreen UIIEnumerator DeathScreen(){    Time.timeScale = 1f / slowness;    Time.fixedDeltaTime = Time.fixedDeltaTime / slowness;    yield return new WaitForSeconds(1f / slowness);    Time.timeScale = 1f;    Time.fixedDeltaTime = Time.fixedDeltaTime * slowness;    deathMenuUI.SetActive(true);    Time.timeScale = 0f;    GameOver = true;}//if game is continued, close deathUI and start timerpublic void continueGame(){    deathMenuUI.SetActive(false);    Time.timeScale = 1f;    GameOver = false;    StartCoroutine(LoseTime());}private void Update(){    countDownText.text = ("" + timeLeft);    if (timeLeft <= 0)    {        StopCoroutine(LoseTime());    }}IEnumerator LoseTime(){    while (true)    {        countDownUI.SetActive(true);        CountDown = true;        yield return new WaitForSeconds(1);        timeLeft--;    }}}
查看完整描述

1 回答

?
aluckdog

TA贡献1847条经验 获得超7个赞

由于您设置Time.timeScale = 0暂停游戏,因此您需要使用WaitForSecondsRealtime而不是WaitForSeconds(就像@Prodian 在评论部分建议的那样),因为WaitForSecondsRealtime使用未缩放的时间,无论您设置什么值都不会受到影响Time.timeScale。


我在这里对您的代码进行了一些修改:


//if game is continued, close deathUI and start timer

public void continueGame()

{

    // Add this line to prevent accident like double click... which will start multiple coroutine and cause unexpected result

    if (CountDown) return;

    CountDown = true;

    deathMenuUI.SetActive(false);

    // Since you want your game to still being paused for 3 seconds before resuming

    Time.timeScale = 0;

    StartCoroutine(LoseTime());

}


private void AfterCountdownFinished()

{

    // important. You must set your Time.timeScale back to its default value

    // because even if you reload your scene the timeScale remain the same which can cause you to encounter freeze error which you might spend time to search for the problem


    Time.timeScale = 1;

    GameOver = CountDown = false;

    countDownUI.SetActive(false);

    // You want to write your restart/continue logic here

    // Example:

    // reload the level

    // SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);

}


IEnumerator LoseTime()

{

    // I forgot this part (which you pointed out)

    countDownUI.SetActive(true);

    // Here is how you can improve performance


    // It seems you can't create and reuse it like WaitForSeconds

    // var delay = new WaitForSecondsRealtime(1);

    // Set this the text here so it will display (3 in your case) for 1 second before start decreasing

    countDownText.text = timeLeft.ToString();


    // If your level will restart after the countdown ends then you don't need to create another variable like below. You can just use timeLeft directly

    int time = timeLeft;

    while (time > 0)

    {

        // Edited here

        yield return new WaitForSecondsRealtime(1);

        time--;

        // Here you don't set your UI text every frame in the update but you only set it only when there is change on timeLeft

        countDownText.text = time.ToString();

    }

    // When countdown ended. You don't need to call StopCoroutine

    AfterCountdownFinished();

}

如果您的 UI 有某种Time.deltaTime用于制作动画的动画,那么您需要将其更改为使用Time.unscaledDeltaTime。它与WaitForSecondsand 的想法相同WaitForSecondsRealtime,一个受Time.timeScale值影响而另一个不受值影响。


PS:我Update完全删除了你的功能,因为如果你按照我的方式实现你就不需要它了。而且你不需要在StopCoroutine任何地方打电话,因为倒计时结束时会自动停止


查看完整回答
反对 回复 2021-11-14
  • 1 回答
  • 0 关注
  • 309 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信