Theo Crowley
Theo Crowley

Reputation: 123

Operation is not valid due to the current state of the object (System.Iinq)

So i'm making a basic 2D platformer in Unity, I want to be able to save the time it takes the player to complete each level and display the fastest time in a UI element. I'm writing the times to a text file (this works fine), and reading all the times line by line into a list, from there I find the lowest value etc. However, my code does not work, it gives me the following error when I'm calling the function from another script. I'm new to C# so would greatly appreciate any help anyone can give me!

Thanks!

Full Error Message

InvalidOperationException: Operation is not valid due to the current state of the object System.Linq.Enumerable.Iterate[Single,Single] (IEnumerable1 source, Single initValue, System.Func3 selector) System.Linq.Enumerable.Min (IEnumerable`1 source) SaveScores.ReadData (System.String LevelLoaded) (at Assets/Scripts/Highscores/SaveScores.cs:73) GameManager.Update () (at Assets/Scripts/GameManager.cs:45)

Code

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System;
using System.Linq;

public class SaveScores : MonoBehaviour {

void Start()
{
    //ReadData();
}

public static void WriteData(float time, string LevelLoaded)
{
    try
    {
        //Debug.Log("Saving time");
        StreamWriter sw = new StreamWriter(@"C:\Users\Theo\Documents\Unity Projects\V13\Platformer\Assets\Scripts\Highscores\Scores.txt", true);
        sw.WriteLine(LevelLoaded + " " + time);

        sw.Close();
    }
    catch(Exception e)
    {
        Console.WriteLine("Exception: " + e.Message);
    }
    finally
    {
        Console.WriteLine("Executing final block");
    }
}

public static void ReadData(string LevelLoaded)
{
    List <float> timesLevel1 = new List<float>();
    List <float> timesLevel2 = new List<float>();
    List <float> timesLevel3 = new List<float>();

    try
    {
        var lines = File.ReadAllLines(@"C:\Users\Theo\Documents\Unity Projects\V13\Platformer\Assets\Scripts\Highscores\Scores.txt");

        foreach (var line in lines)
        {
            if (line.Contains("Level1"))
            {
                timesLevel1.Add(Convert.ToSingle(line));
            }
            else if (line.Contains("Level2"))
            {
                timesLevel2.Add(Convert.ToSingle(line));
            }
            else if (line.Contains("Level3"))
            {
                timesLevel3.Add(Convert.ToSingle(line));
            }
        }
    }
    catch (Exception e)
    {
        Console.WriteLine("Exception: " + e.Message);
    }
    finally
    {
        Console.WriteLine("Executing final block");
    }

    switch (LevelLoaded)
    {
        case "Level1":
            UIManager.lowestTime = timesLevel1.Min();
            break;
        case "Level2":
            UIManager.lowestTime = timesLevel2.Min();
            break;
        case "Level3":
           UIManager.lowestTime = timesLevel3.Min();
            break;
    }

}

}

Upvotes: 0

Views: 2406

Answers (1)

Chris
Chris

Reputation: 27609

If you look at the documentation for Enumerable.Min<float> (https://msdn.microsoft.com/en-us/library/bb361144(v=vs.110).aspx) you will see that under "Exceptions" it lists the InvalidOperationException and gives the reason as: "source contains no elements".

What this likely means is that the list you are looking at doesn't contain any elements.

On looking at what is populating that list there seems to be some confusion in what you expect to be in the line. You do a test for line.Contains("Level1") but if that succeeds then you call Convert.ToSingle(line) which would fail if there was any string data in that line (eg if line did contain that string then the convert would fail).

So it seems likely that the format of the file you are reading is not what you expect it to be leading to your lists being empty leading to this error.

Upvotes: 1

Related Questions