private IEnumerator SimulateGeneration() { var solutions = new Solution[Settings.PopulationSize]; var solutionIndex = 0; // Prepare batch simulation int actualBatchSize = Settings.SimulateInBatches ? Settings.BatchSize : Settings.PopulationSize; int numberOfBatches = (int)Math.Ceiling((double)this.Settings.PopulationSize / actualBatchSize); int firstChromosomeIndex = 0; // Cache values that can be changed during the simulation this.cachedSettings = this.Settings; if (NewGenerationDidBegin != null) { NewGenerationDidBegin(); } for (int i = 0; i < numberOfBatches; i++) { this.currentBatchNumber = i + 1; int remainingCreatures = Settings.PopulationSize - (i * actualBatchSize); int currentBatchSize = Math.Min(actualBatchSize, remainingCreatures); var sceneLoadConfig = new SceneController.SimulationSceneLoadConfig( this.SimulationData.CreatureDesign, currentBatchSize, this.SimulationData.SceneDescription, SceneController.SimulationSceneType.Simulation, GetLegacySimulationOptions() ); var context = new SceneController.SimulationSceneLoadContext(); var sceneContext = new SimulationSceneContext(this.SimulationData); yield return(SceneController.LoadSimulationScene(sceneLoadConfig, context, sceneContext)); this.batchPhysicsScene = context.PhysicsScene; var batch = context.Creatures; this.currentCreatureBatch = batch; var chromosomeCount = Math.Min(this.SimulationData.CurrentChromosomes.Length, batch.Length); var chromosomes = new float[chromosomeCount][]; for (int c = 0; c < chromosomeCount; c++) { chromosomes[c] = this.SimulationData.CurrentChromosomes[c + firstChromosomeIndex]; } firstChromosomeIndex += batch.Length; ApplyBrains(batch, chromosomes); yield return(SimulateBatch()); // Evaluate creatures and destroy the scene after extracting all // required performance statistics for (int j = 0; j < batch.Length; j++) { var creature = batch[j]; solutions[solutionIndex++] = new Solution() { Encodable = creature.brain.Network, Stats = creature.GetStatistics(this.cachedSettings.SimulationTime) }; } yield return(SceneManager.UnloadSceneAsync(context.Scene)); } EvaluateSolutions(solutions); }