【问题标题】:Collection was modified enumeration operation may not execute - Unity 3d集合已修改枚举操作可能无法执行 - Unity 3d
【发布时间】:2015-03-01 02:13:50
【问题描述】:

我正在做的游戏代码有问题。 我正在尝试在 z 对象上一定米外的玩家被移除时执行此操作,但是我遇到的统一测试冻结并出现此错误:Collection was modified enumeration operation may not execute.

这里是代码

    void Update()
{
    foreach (GameObject gm in GenerateManager.Instante.BloquesGenerados)
    {
        if (Vector3.Distance(PlayerManager.Instanse.gameObject.transform.position, gm.transform.position) > 25)
        {
            Destroy(gm);
            GenerateManager.Instante.BloquesGenerados.Remove(gm);
        }
    }

【问题讨论】:

  • 您无法修改foreach 中的集合。而不是使用for

标签: c# foreach unity3d


【解决方案1】:

添加ToList(),它将创建一个具有相同项目的新集合:

foreach (GameObject gm in GenerateManager.Instante.BloquesGenerados.ToList())

您不能修改 (GenerateManager.Instante.BloquesGenerados.Remove) 正在使用 foreach 迭代的集合。

【讨论】:

    【解决方案2】:

    简单地向后迭代:

    for(int i=GenerateManager.Instante.BloquesGenerados.Count - 1; i>=0; i--){
        var gm = GenerateManager.Instante.BloquesGenerados[i];
        if(Vector3.Distance(PlayerManager.Instanse.gameObject.transform.position,gm.transform.position) > 25){ 
    
            Destroy(gm); 
            GenerateManager.Instante.BloquesGenerados.Remove(gm);
        }
    

    您不必复制该集合。您可以节省时间和空间(内存方面)。

    【讨论】:

    • 如果您开始在循环中使您的逻辑复杂化,那么在这种情况下很容易出现错误。您以性能取胜,但失去了可读性和可维护性。
    • 谢谢你,解决了它:)
    • @Gabe 您可以一次开始删除多个项目,但整个想法都失败了。
    • @Gabe 是的,当我谈论您的业务逻辑的复杂性时,这就是我所说的。在实际项目中,它每次都会发生。这是一种预防性优化,可能会导致数小时的调试。
    • @Gabe 您正在编写具有误导性的代码(您应该在循环中添加注释以解释您可以做什么和不能做什么以避免错误,是的,没有人阅读 cmets)或者只是不完成(您应该在循环中放置一个索引保护)。
    猜你喜欢
    • 2015-06-17
    • 2020-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-17
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多