每次调用协程函数时,都会修改timeLeft 变量。如果您在第一个协程函数正在运行时再次调用该协程函数,那么多个协程函数将同时修改 timeLeft 变量,从而导致您当前的问题。
一种解决方案是使用布尔变量来检测协程何时已经运行并再次启动,但您提到要同时创建多个计时器。你有两个选择:
1.将timeLeft 变量移到Countdown 函数中,以便每个函数调用都有一个timeLeft 变量。也对countText 变量执行相同操作,以便在每个函数调用中使用不同的Text 组件来修改Text。
public IEnumerator Countdown()
{
float timeLeft = 5f;
Text countText = GameObject.Find("TextForThisCounter").GetComponent<Text>();
while (timeLeft > 0)
{
yield return new WaitForSeconds(1.0f);
countText.text = timeLeft.ToString("f0");
timeLeft--;
}
}
2.将整个协程函数移动到另一个类,然后使用回调Action 来通知您每秒有一个计时器滴答声以及计时器何时完成。我推荐这种方法,因为它更便携和可重用。您还可以实现一个 ID 来确定它完成运行时是哪个计时器。
定时器移到另一个脚本:
public struct CountDownTimer
{
private static int sTimerID = 0;
private MonoBehaviour monoBehaviour;
public int timer { get { return localTimer; } }
private int localTimer;
public int timerID { get { return localID; } }
private int localID;
public CountDownTimer(MonoBehaviour monoBehaviour)
{
this.monoBehaviour = monoBehaviour;
localTimer = 0;
//Assign timer ID
sTimerID++;
localID = sTimerID;
}
public void Start(int interval, Action<int> tickCallBack, Action<int> finshedCallBack)
{
localTimer = interval;
monoBehaviour.StartCoroutine(beginCountDown(tickCallBack, finshedCallBack));
}
private IEnumerator beginCountDown(Action<int> tickCallBack, Action<int> finshedCallBack)
{
while (localTimer > 0)
{
yield return new WaitForSeconds(1.0f);
localTimer--;
//Notify tickCallBack in each clock tick
tickCallBack(localTimer);
}
//Notify finshedCallBack after timer is done
finshedCallBack(localID);
}
}
用法:
启动计时器 4 次,每次使用不同的 ID。
void Start()
{
createAndStartNewTimer();
createAndStartNewTimer();
createAndStartNewTimer();
createAndStartNewTimer();
}
public void createAndStartNewTimer()
{
//Create new Timer
CountDownTimer timer = new CountDownTimer(this);
//What to do each second time tick in the timer
Action<int> tickCallBack = (timeLeft) =>
{
Debug.Log(timeLeft.ToString("f0"));
};
//What to do each second time tick in the timer
Action<int> finshedCallBack = (timeriD) =>
{
Debug.Log("Count Down Timer Done! ID: " + timeriD);
};
//Start Countdown Timer from 5
timer.Start(5, tickCallBack, finshedCallBack);
}