Help with Having GameObject Scripts Read data in CSV or Txt File

Everyone,

I am a doctoral student in a collaborative effort with another doctoral student, right now we are trying figure out how to integrate Vissim (a transportation simulation anlaysis software) with Unity. Currently, the way have been approaching it is by running simulations in Vissim, collecting data from the Vissim output (e.g. vehicle no., simulation time, position in the x, y, z), and converting this data into a CSV and text file to see if we can get a cube object to move around the Unity gaming environment according to the Vissim simulation outputs. We were wondering is there any code or script that performs the activity of reading the CSV or text file in Unity, to allow cube in our gaming environment to be moved in the same pattern as that in our Vissim simulation? For more information and reference, the text file that we were hoping to import our data from can is attached below.

Also, as more of a challenge, is there an easier way of doing this, such as maybe, having the data directly read from Vissim in real-time as the simulation is running into Unity?

Thanks for the help.

5007767–489740–Veh1.txt (12.6 KB)

Just read it yourself in C#. Your data is trivial enough to just use String.Split by comma and some TryParse calls to pluck the values out into usable floats.

There’s probably an official C# package to read CSV if you insist, but if you use a third-party CSV reading package, it has to be fully compatible with the exact flavor of .NET that Unity uses, which can get can-of-worms-y.

To get it into Unity live, you’d need some kind of bridge, maybe some web service that presents the data, then read it realtime from Unity.

String.Split works fine for very simple CSV files, but if they’ve got quoted entries or escape characters you’ll run into trouble.

For parsing CSV data in Unity, I am currently using a Regex I grabbed from this StackOverflow question. My code goes something like this:

// Tells the parser which column number to look in for each field
protected enum Columns : int
{
    ID = 0,
    Name,
    Description,
    Etc
}
protected const int numHeaderRows = 1;    // Rows to ignore at start of CSV file

// Load definitions from the data in a CSV file
// Returns a string containing errors/warnings from parsing (will be empty if everything looks fine)
protected virtual string LoadDefinitionsFromString(string dataString)
{
    // Covering bases against different line endings by splitting on both \r and \n
    // and then removing blank entries
    string[] lines = dataString.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
    return LoadDefinitionsFromLines(lines);
}
protected virtual string LoadDefinitionsFromLines(string[] lines)
{
    StringBuilder errs = new StringBuilder();
    try
    {
        loadingDefinitions = true;

        Clear();

        for (int l = numHeaderRows; l < lines.Length; ++l)
        {
            // Regex-based parsing of the line based on https://stackoverflow.com/questions/3268622/regex-to-split-line-csv-file
            List<string> columns = new List<string>();
            try
            {
                Regex pattern = new Regex(@"
                            # Parse CVS line. Capture next value in named group: 'val'
                            \s*                      # Ignore leading whitespace.
                            (?:                      # Group of value alternatives.
                                ""                     # Either a double quoted string,
                                (?<val>                # Capture contents between quotes.
                                [^""]*(""""[^""]*)*  # Zero or more non-quotes, allowing
                                )                      # doubled "" quotes within string.
                                ""\s*                  # Ignore whitespace following quote.
                            |  (?<val>[^,]*)         # Or... zero or more non-commas.
                            )                        # End value alternatives group.
                            (?:,|$)                  # Match end is comma or EOS",
                    RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace);
                Match matchResult = pattern.Match(lines[l]);
                while (matchResult.Success)
                {
                    columns.Add(matchResult.Groups["val"].Value.Replace("\"\"", "\"").Replace("''", "'"));
                    matchResult = matchResult.NextMatch();
                }
            }
            catch (ArgumentException ex)
            {
                // Syntax error in the regular expression
                errs.Append("Row ");
                errs.Append(l);
                errs.Append(" CSV error: ");
                errs.Append(ex.Message);
                errs.Append("\n");
                continue;
            }



            // Process this particular row

            // Make sure the ID parses
            int IDnum;
            if (!int.TryParse(GetCol(columns, Columns.ID), out IDnum))
            {
                errs.Append("Couldn't parse ID on line ");
                errs.Append(l);
                errs.Append("\n");
                continue;  // Skip this row and move on to the next one
            }

            // etc

        }
    }
    finally
    {
        loadingDefinitions = false;
    }

    if (OnDefinitionsChanged != null) OnDefinitionsChanged();

    string errStr = errs.ToString();
    return errStr;
}

// Helper function that hides the cast from Columns enum to int
// (just for readability)
protected static string GetCol(IList<string> columns, Columns col)
{
    return columns[(int)col];
}