我正在尝试创建一个倒计时计时器,当我的玩家在游戏重新开始之前购买了3秒的第二生命时。我不确定下面需要修复什么才能让它工作。目前,所有up都会在应该弹出的时候弹出,倒计时计时器文本也会弹出,但游戏仍在继续,计时器停留在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 UI
IEnumerator 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 timer
public 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--;
}
}}
发布于 2018-08-03 18:08:41
由于你将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。这与WaitForSeconds和WaitForSecondsRealtime的想法相同,一个受Time.timeScale值影响,而另一个则不受影响。
PS:我完全删除了你的Update函数,因为如果你以我的方式实现,你就不需要它了。而且您不需要在任何地方调用StopCoroutine,因为倒计时将在结束时自动停止
https://stackoverflow.com/questions/51666447
复制相似问题