C# 如何解决无效操作异常?
在我的Unity项目中,我有一个C# 如何解决无效操作异常?,c#,arrays,unity3d,C#,Arrays,Unity3d,在我的Unity项目中,我有一个LevelGenerator创建Stages(游戏对象)并将其添加到列表中。当我临终时,我想销毁并删除列表中的所有项目。但当我在列表中迭代时,只有第一个对象被销毁并删除,然后发生错误: InvalidOperationException:集合已修改;枚举操作可能无法执行。 System.ThrowHelper.ThrowInvalidOperationException(System.ExceptionResource)(位于:0) System.Collecti
LevelGenerator
创建Stages
(游戏对象)并将其添加到列表中。当我临终时,我想销毁并删除列表中的所有项目。但当我在列表中迭代时,只有第一个对象被销毁并删除,然后发生错误:
InvalidOperationException:集合已修改;枚举操作可能无法执行。System.ThrowHelper.ThrowInvalidOperationException(System.ExceptionResource)(位于:0)
System.Collections.Generic.List
1+枚举数[T].MoveNextRare()(at:0)System.Collections.Generic.List
1+枚举数[T].MoveNext()(at:0)
你能帮我吗
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LevelGenerator : MonoBehaviour
{
private const float PLAYER_DISTANCE_SPAWN_LEVEL_PART = 25f;
[SerializeField] private Transform Startingstage;
[SerializeField] private List<Transform> StageList;
[SerializeField] private Transform player;
public List<GameObject> gameObjectsToDestroy;
public bool creatingGoesOn = false;
private Vector3 lastEndPosition;
public void CreateEnviroment() // Every time called when game is started
{
lastEndPosition = Startingstage.Find("EndingPoint").position;
int startingSpawnLevelParts = 7;
for (int i = 0; i < startingSpawnLevelParts; i++)
{
SpawnLevelPart();
}
creatingGoesOn = true;
}
private void Update()
{
if (creatingGoesOn)
{
if (Vector3.Distance(player.position, lastEndPosition) < PLAYER_DISTANCE_SPAWN_LEVEL_PART)
{
// Spawn a new level part if player is to close to the end.
SpawnLevelPart();
}
}
}
private void SpawnLevelPart()
{
Transform randomStage = StageList[Random.Range(0, StageList.Count)];
Transform lastLevelPartTransform = SpawnLevelPart(randomStage, lastEndPosition);
lastEndPosition = lastLevelPartTransform.Find("EndingPoint").position;
}
private Transform SpawnLevelPart(Transform stage, Vector3 spawnPosition)
{
Transform levelPartTransform = Instantiate(stage, spawnPosition, Quaternion.identity);
gameObjectsToDestroy.Add(levelPartTransform.gameObject);
return levelPartTransform;
}
}
只要您看到
invalidoOperationException:Collection被修改;枚举操作可能不会执行
,如果在单个线程上访问相关集合,则您应该知道这是因为您正在修改要迭代的相同列表
这通常发生在使用使用IEnumerable
的功能时,例如:
循环与您的情况相同foreach
GetEnumerator()
循环中常见的解决方案是考虑一个对你的问题有意义的不同结构。
如果需要,我还可以提供一种在您的案例中应用此方法的方法。请告诉我。您的问题是在迭代列表时从列表中删除项目,这会更改列表的大小 最简单的方法可能是
foreach (GameObject toDestroy in destroyEnviroment.gameObjectsToDestroy)
{
Destroy(toDestroy);
}
destroyEnviroment.gameObjectsToDestroy.Clear();
编辑:值得注意的是,这里我
Destroy
在删除之前,这似乎违反直觉,但原因是调用Destroy将在帧结束时设置要销毁的对象,然后我们可以忘记它并清除列表-其他一切都将得到处理。如果不需要,我极力主张不要从列表中删除项目——在这种情况下,您将清除整个列表,因此您可以使用
clear()
,但在这种情况下,您实际上不需要更改循环类型,Jay建议在循环之外清除它的内容在您的情况下就足够了。有时在某些情况下它可能不起作用。我倾向于使用的另一个选项是while(collection.Any)
,如果您知道要清除列表中的每个项目。请记住,如果从一开始就删除元素(如列表),某些数据类型可能是O(n)
。谢谢。我是新的团结,这是非常推动我前进。你最好<代码>foreach(GameObject toDestroy in Destroyment Environment.gameObjectsToDestroy.ToList())
Thx。但是为什么不使用while循环(list.Count>0),在该循环中销毁并从列表中删除元素[0]?在我的情况下,它总是出现:“不在范围内”。@Thboss将更新我的答案以回应此问题
foreach (GameObject toDestroy in destroyEnviroment.gameObjectsToDestroy)
{
Destroy(toDestroy);
}
destroyEnviroment.gameObjectsToDestroy.Clear();