unity3d - foreach 中列表的奇怪行为
问题描述
我有一个在运行时跟踪“活动”对象的列表。当我在这个列表中的项目中应用一些行为时,我发现了一些奇怪的东西(至少对我来说),例如,假设我想伤害当前场景中的每个敌人,所以(项目是自定义类的列表)
if (Input.GetKeyDown(KeyCode.C))
{
var enemiesWithLife = enemiesInScene.Items.FindAll(enemy => enemy.life > 1);
foreach (var enemy in enemiesWithLife)
enemy.TakeDamage(1);
}
上面的代码按预期工作但是如果我想对所有敌人应用一些东西并尝试一些东西
if (Input.GetKeyDown(KeyCode.C))
{
foreach (var enemy in enemiesInScene.Items)
enemy.TakeDamage(1);
}
当我按“C”时,只有 1 个敌人“TakeDamage”,并且在迭代期间修改了有关列表的错误
- EnemiesInScene 是一个 ScriptableObject,因此敌人列表仅存在于资产中
但是,如果我尝试相同的代码,但之前进行了查找,如
if (Input.GetKeyDown(KeyCode.C))
{
var allEnemies = enemiesInScene.Items.FindAll(enemy => true);
foreach (var enemy in allEnemies)
enemy.TakeDamage(1);
}
事情再次按预期工作......为什么?
编辑
评论中询问的代码:
public void TakeDamage(int damage)
{
if (currentLife <= 0)
return;
currentLife -= damage;
if (currentLife <= 0)
Die();
else
TakeHit();
}
EnemiesInScene 是一个 RuntimeSet
public class RuntimeSet : ScriptableObject
{
public List<RuntimeItem> Items = new List<RuntimeItem>();
public void Add(RuntimeItem thing)
{
if (!Items.Contains(thing))
Items.Add(thing);
}
public void Remove(RuntimeItem thing)
{
if (Items.Contains(thing))
Items.Remove(thing);
}
}
运行时项
public class RuntimeItem : LazyComponents
{
public RuntimeSet runtimeSet;
private void OnEnable()
=> runtimeSet.Add(this);
private void OnDisable()
=> runtimeSet.Remove(this);
}
并且 LazyComponents 只是一个惰性方法包装器,它继承自 monobehaviour 以获取一些组件作为rigidbody2d 等......
解决方案
for (int i = list.Count - 1; i != -1; i--)
list.RemoveAt(i); // replace with useful code that can modify this list
推荐阅读
- html - 为什么我的 HTML 数字输入卡在步骤 0.010000000000000009 上?
- php - 在我的 laravel 包测试中找不到视图
- python - 将行类别转换为列
- node.js - 发布一个简单的react表单——node、axios、nodemailer、backend、postman
- apache-commons-csv - 使用 CSVPrinter 从 CSVFormat 打印标题
- r - 在地图上添加颜色编码的图例以指示阴影县
- reactjs - React SSR - redux-persist 无法创建同步存储
- email - 为什么Nodemailer邮箱达到上限?
- r - R:绘制函数 f(x,y)=c,其中 c 以 1 的间隔增加
- mongodb - 有没有办法用 MongoDB 中的随机值更新集合中的所有文档?