C# 值在协同程序内未准确递增

C# 值在协同程序内未准确递增,c#,unity3d,coroutine,timedelta,C#,Unity3d,Coroutine,Timedelta,我不熟悉C#和Unity。我试图每5秒增加一个值(计数器)。但是,该值每5秒增加4。当数值达到5时,计数器也应停止。但是,它继续增加,直到我手动停止它 public float energyLevel = 0; public IEnumerator DoIncrement() { while (true) { while ((Math.Abs(Counter - 5) > Mathf.Epsilon)) {

我不熟悉C#和Unity。我试图每5秒增加一个值(计数器)。但是,该值每5秒增加4。当数值达到5时,计数器也应停止。但是,它继续增加,直到我手动停止它


public float energyLevel = 0;

public IEnumerator DoIncrement()
 {
     while (true)
     {
         while ((Math.Abs(Counter - 5) > Mathf.Epsilon)) 
         {
         float duration = 5f; 
         float nTime = 0;
             while (nTime <= 1f)
             {
                 nTime += Time.deltaTime / duration;
                 yield return null;
             }
         Counter++;
         Debug.Log("Counter = " + Counter);
         }
     StopCoroutine(DoIncrement());
     yield return null;
     break;
     }
 }

公共浮点数energyLevel=0;
公共IEnumerator DoIncrement()
{
while(true)
{
while((Math.Abs(计数器-5)>Mathf.Epsilon))
{
浮动持续时间=5f;
浮动时间=0;
而(nTime替换这些行:

 StopCoroutine(DoIncrement());
 yield return null;
 break;
通过简单的休息;或屈服休息;两者都会起作用

您的问题是“StopCorroutine(DoIncrement())”将递归地对DoIncrement进行新调用,您永远不会停止。StopCorroutine()不能以这种方式用于迭代器(绝对不需要从内部停止)。

替换以下行:

 StopCoroutine(DoIncrement());
 yield return null;
 break;
通过简单的休息;或屈服休息;两者都会起作用


您的问题是“StopCorroutine(DoIncrement())”将以递归方式对DoIncrement进行新调用,您永远不会停止。StopCorroutine()不能以这种方式用于迭代器(并且绝对不需要从内部停止它).

首先,您不必停止协同程序本身。当它到达代码末尾时,它会自动停止

下面是一个简单的工作示例,您可以使用:

    private void Awake()
    {
        StartCoroutine(IncrementCoroutine(5, 1));
    }

    private IEnumerator IncrementCoroutine(int maxCounter, float timeBetweenIncrement)
    {
        WaitForEndOfFrame endofFrame = new WaitForEndOfFrame();
        int counter = 0;
        float timer = 0;

        while (counter < maxCounter)
        {
            print($"Counter : {counter}");
            while (timer < timeBetweenIncrement)
            {
                timer += Time.deltaTime;
                yield return endofFrame;
            }

            timer = 0;
            counter++;
        }
    }
private void Awake()
{
startcroutine(incrementcorroutine(5,1));
}
私有IEnumerator增量协同路由(int maxCounter,float timebetween增量)
{
WaitForEndOfFrame endofFrame=新的WaitForEndOfFrame();
int计数器=0;
浮动计时器=0;
while(计数器<最大计数器)
{
打印($“计数器:{Counter}”);
while(计时器<时间间隔增量)
{
timer+=Time.deltaTime;
收益内框架;
}
定时器=0;
计数器++;
}
}

首先,您不必停止协同程序本身。当它到达代码末尾时,它会自动停止

下面是一个简单的工作示例,您可以使用:

    private void Awake()
    {
        StartCoroutine(IncrementCoroutine(5, 1));
    }

    private IEnumerator IncrementCoroutine(int maxCounter, float timeBetweenIncrement)
    {
        WaitForEndOfFrame endofFrame = new WaitForEndOfFrame();
        int counter = 0;
        float timer = 0;

        while (counter < maxCounter)
        {
            print($"Counter : {counter}");
            while (timer < timeBetweenIncrement)
            {
                timer += Time.deltaTime;
                yield return endofFrame;
            }

            timer = 0;
            counter++;
        }
    }
private void Awake()
{
startcroutine(incrementcorroutine(5,1));
}
私有IEnumerator增量协同路由(int maxCounter,float timebetween增量)
{
WaitForEndOfFrame endofFrame=新的WaitForEndOfFrame();
int计数器=0;
浮动计时器=0;
while(计数器<最大计数器)
{
打印($“计数器:{Counter}”);
while(计时器<时间间隔增量)
{
timer+=Time.deltaTime;
收益内框架;
}
定时器=0;
计数器++;
}
}

有一种方法,您可以在其中创建WaitForSecondRealTime对象,并通过任何您想要保持迭代的秒数

返回新的waitforsecondrealtime(X);

上面的语句将停止您的协同程序执行X秒


并且计数器+=1计数器+++在每次执行时都会添加1。

有一种方法,您可以在其中创建WaitForSecondsRealtime对象,并通过您想要保持迭代的任何秒数

返回新的waitforsecondrealtime(X);

上面的语句将停止您的协同程序执行X秒


计数器+=1计数器+++在每次执行时都会加1。

如果在它的末尾中断,并且在任何地方都没有使用
continue
,那么将它包装在while循环中是没有意义的

您不需要从协同程序内部使用
StopCoroutine
来停止它,只需允许该方法返回即可

您无法保证计数器将接近5的值,因此您的while循环可能永远不会终止。最好在计数器低于某个值时循环

我建议使用
WaitForSeconds
之类的方法来处理时间计数,而不是自己做:

private int Counter = 0; // define Counter
public float energyLevel = 0;

public IEnumerator DoIncrement()
 {
     WaitForSeconds waiter = new WaitForSeconds(5f);
     while (Counter < 5) 
     {
         yield return waiter;
         Counter++;
         Debug.Log("Counter = " + Counter);
     }
 }
private int Counter=0;//定义计数器
公共浮点数energyLevel=0;
公共IEnumerator DoIncrement()
{
WaitForSeconds服务员=新的WaitForSeconds(5f);
while(计数器<5)
{
退换货服务员;
计数器++;
Debug.Log(“计数器=”+计数器);
}
}

此外,该问题没有包含足够的信息,无法重现计数器在5秒钟内多次增加的问题。这部分问题无法得到充分回答。这可能是由于您一次启动了4次协同程序造成的。

如果您在en处中断,那么将其包装在while循环中是没有意义的d,并且在任何地方都没有使用
continue

您不需要从协同程序内部使用
StopCoroutine
来停止它,只需允许该方法返回即可

您无法保证计数器将接近5的值,因此您的while循环可能永远不会终止。最好在计数器低于某个值时循环

我建议使用
WaitForSeconds
之类的方法来处理时间计数,而不是自己做:

private int Counter = 0; // define Counter
public float energyLevel = 0;

public IEnumerator DoIncrement()
 {
     WaitForSeconds waiter = new WaitForSeconds(5f);
     while (Counter < 5) 
     {
         yield return waiter;
         Counter++;
         Debug.Log("Counter = " + Counter);
     }
 }
private int Counter=0;//定义计数器
公共浮点数energyLevel=0;
公共IEnumerator DoIncrement()
{
WaitForSeconds服务员=新的WaitForSeconds(5f);
while(计数器<5)
{
退换货服务员;
计数器++;
Debug.Log(“计数器=”+计数器);
}
}
此外,该问题包含的信息不足,无法重现计数器在5秒内多次增加的问题。该部分无法得到充分回答。这可能是由于您启动协同程序造成的