private IEnumerator Erode() { while (true) // aaaaaagh!!! { bool noActiveOrFallingAtoms = true; for (int i = 0; i < AtomsPerSide; i++) { AtomState[] row = _floorState[i]; for (int j = 0; j < AtomsPerSide; j++) { AtomState atomState = row[j]; switch (atomState) { case AtomState.Disabled: break; case AtomState.Active: int fallenNeighbours = GetFallenNeighbourCount(i, j); if (fallenNeighbours > 0) { if (fallenNeighbours > 2 || Random.value * fallenNeighbours < EdgeFallChance) { _fallBuffer.Add(new IntPair(i, j)); } } else if (Random.value < InnerFallChance) { _fallBuffer.Add(new IntPair(i, j)); } noActiveOrFallingAtoms = false; break; case AtomState.Falling: Rigidbody atom = _floorAtoms[i][j]; if (atom.transform.position.y < DisableDepth) { atom.gameObject.SetActive(false); row[j] = AtomState.Disabled; } noActiveOrFallingAtoms = false; break; default: throw new ArgumentOutOfRangeException(); } } yield return(_wait); } int count = _fallBuffer.Count; for (int x = 0; x < count; x++) { IntPair atomPos = _fallBuffer[x]; int i = atomPos.I; int j = atomPos.J; _floorAtoms[i][j].isKinematic = false; _floorState[i][j] = AtomState.Falling; } _fallBuffer.Clear(); if (noActiveOrFallingAtoms) { break; } } }