When I try to remove some elements of a list using the UniRx library, I'm getting the following error:
InvalidOperationException: Collection was modified; enumeration operation may not execute.
This is the code responsible of the removal:
Observable
.EveryUpdate()
.SelectMany(_ => _gameState.enemies)
.Where(enemy => enemy.x > 5)
.Subscribe(enemy =>
{
_gameState.enemies.Remove(enemy);
})
One possible solution is to generate a new List as result of SelectMany
, such as _gameState.enemes.ToList()
, but I was wondering if there's an allocation-free alternative.
In case there is not, what other approaches are there while using observables to achieve this?
If I understand correctly the _gameState.enemies
is actually a plain List
of some enemy instances.
I think you just overcomplicated it by chaining the subscription that way.
To me it looks like RemoveAll
would be your best option
Observable.EveryUpdate().Subscribe(() =>
{
_gameState.enemies.RemoveAll(enemy => enemy.x > 5);
});
Update as to the comment:
Since _gameState.enemies
is a RectiveCollection<Enemy>
you could indeed use (from https://stackoverflow.com/a/15277219/7111561)
Observable.EveryUpdate().Subscribe(() =>
{
for (int i = _gameState.enemies.Count - 1; i >= 0; i--)
{
if (_gameState.enemies[i].x > 5)
{
_gameState.enemies.RemoveAt(i);
}
}
});
or have this as extension method of course