C#IEnumerator是不可变的

时间:2016-08-24 11:41:48

标签: c# unity3d

我遇到以下代码的问题。它的作用是建立一条单一的道路,一个接一个的元素。

currentLength = Random.Range(maxFloorLength - 2, maxFloorLength);
    List<GameObject> tempList = new List<GameObject>();

    for (int i = 0; i < currentLength; ++i)
    {
        foreach (GameObject g in pooledFloor)
        {
            if (!g.activeInHierarchy)
            {
                g.SetActive(true);
                g.transform.position = startPoint + buildDirection * i;
                g.transform.DOScaleY(5, 0.25f).Play();
                lastFloorPositions.Add(g.transform.position);
                tempList.Add(g);
                break;
            }
        }
        yield return new WaitForSeconds(0.05f);
    }

虽然这可以按预期工作,但当我将其更改为:

    currentLength = Random.Range(maxFloorLength - 2, maxFloorLength);
    List<GameObject> tempList = new List<GameObject>();

    for (int i = 0; i < currentLength; ++i)
    {
        foreach (GameObject g in pooledFloor)
        {
            if (!g.activeInHierarchy)
            {
                g.transform.position = startPoint + buildDirection * i;
                lastFloorPositions.Add(g.transform.position);
                tempList.Add(g);
                break;
            }
        }
    }

    foreach (GameObject g in tempList)
    {
        g.SetActive(true);
        g.transform.DOScaleY(5, 0.25f).Play();
        yield return new WaitForSeconds(0.05f);
    }

所有这一切都是创建道路的一部分(应该在tempList列表的末尾)。我想要的是该脚本将所有预制件添加到列表之前与他们做其他事情,所以我可以在它们之间添加一些东西。我试图将其更改为void函数,并将此代码作为ienumerator调用,更改循环类型等但似乎没有任何工作,我不知道为什么它不起作用。我用Debug.Log检查它是否仍然找到超过1个预制件,但确实如此,但它只激活并扩展其中一个。我敢打赌它显而易见,但我无法看到它:/

外观如何:

How its working

它应该如何看待:

How it should look

忘了提及 - 它全部在IEnumerator中

3 个答案:

答案 0 :(得分:2)

在第一个代码中,当您调用g.SetActive(true);时,在for循环的下一次迭代中,同一对象的if条件将不为真,因此它将评估下一个非活动对象并添加它到tempList

for loop的所有迭代的第二种情况下,它继续评估相同的对象g(pooledFloor上的第一个非活动对象),因为它没有被激活。

为了实现您的预​​期行为,我建议您在for-loop上使用for-each代替pooledFloor,如果该对象处于非活动状态,则从列表中删除该对象。

类似的东西:

for (int i = 0; i < currentLength; ++i)
{
    for (int j = 0; j < pooledFloor.Count; j++) 
    {
        GameObject g = pooledFloor[j];
        if (!g.activeInHierarchy)
        {
            g.transform.position = startPoint + buildDirection * i;
            lastFloorPositions.Add(g.transform.position);
            tempList.Add(g);
            pooledFloor.Remove(g);  // Removing it from list would solve the problem.
            break;
        }
    }
}

答案 1 :(得分:0)

第一遍是嵌套而第二部分不是。尝试:

for (int i = 0; i<currentLength; ++i)
{
    foreach (GameObject g in tempList)
    {
        g.SetActive(true);
        g.transform.DOScaleY(5, 0.25f).Play();
    }
    yield return new WaitForSeconds(0.05f);

}

答案 2 :(得分:0)

这样想:

public void passONE()
    {
        currentLength = Random.Range(maxFloorLength - 2, maxFloorLength);
        List<GameObject> tempList = new List<GameObject>();

        for (int i = 0; i < currentLength; ++i)
        {
            foreach (GameObject g in pooledFloor)
            {
                if (!g.activeInHierarchy)
                {
                    g.transform.position = startPoint + buildDirection * i;
                    lastFloorPositions.Add(g.transform.position);
                    tempList.Add(g);
                    break;
                }
            }
        }
        passTwo(currentLength, tempList);

    }
    private void passTwo(double currentLength,List<GameObject> tempList)
    {


        for (int i = 0; i < currentLength; ++i)
        {
            foreach (GameObject g in tempList)
            {
                g.SetActive(true);
                g.transform.DOScaleY(5, 0.25f).Play();

            }
            yield return new WaitForSeconds(0.05f);
        }


    }