Lightweight CSV reader for Unity

Managing game data in Unity scene objects can get really painful especially when more than one people needs to edit the same thing. It’s usually better to have some data in CSV file where it can be controlled centrally.

When facing this problem I couldn’t find CSV reader for Unity that would have been exactly what I need. i.e. not be very buggy, huge or require new assembly dependencies.
So here is very simple CSV reader for Unity. It is bare bones but still robust enough parse quoted text and comma’s inside text. Reader assumes that csv files are in Resources folder of your Unity project.

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;

public class CSVReader
{
	static string SPLIT_RE = @",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))";
	static string LINE_SPLIT_RE = @"\r\n|\n\r|\n|\r";
	static char[] TRIM_CHARS = { '\"' };

	public static List<Dictionary<string, object>> Read(string file)
	{
		var list = new List<Dictionary<string, object>>();
		TextAsset data = Resources.Load (file) as TextAsset;

		var lines = Regex.Split (data.text, LINE_SPLIT_RE);

		if(lines.Length <= 1) return list;

		var header = Regex.Split(lines[0], SPLIT_RE);
		for(var i=1; i < lines.Length; i++) {

			var values = Regex.Split(lines[i], SPLIT_RE);
			if(values.Length == 0 ||values[0] == "") continue;

			var entry = new Dictionary<string, object>();
			for(var j=0; j < header.Length && j < values.Length; j++ ) {
				string value = values[j];
				value = value.TrimStart(TRIM_CHARS).TrimEnd(TRIM_CHARS).Replace("\\", "");
				object finalvalue = value;
				int n;
				float f;
				if(int.TryParse(value, out n)) {
					finalvalue = n;
				} else if (float.TryParse(value, out f)) {
					finalvalue = f;
				}
				entry[header[j]] = finalvalue;
			}
			list.Add (entry);
		}
		return list;
	}
}

Drop this in your Scripts folder as CSVReader.cs and make folder Resources under your Assets folder. Put there any CSV files you want to use.

Example CSV file example.csv in Resources folder.

name,age,speed,description
cat,2,4.5,"cat stalks, jumps and meows"
dog,2,5.5,dog barks
fish,1,1.1,fish swims

How to use

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Main : MonoBehaviour {

	void Awake() {

		List<Dictionary<string,object>> data = CSVReader.Read ("example");

		for(var i=0; i < data.Count; i++) {
			print ("name " + data[i]["name"] + " " +
			       "age " + data[i]["age"] + " " +
			       "speed " + data[i]["speed"] + " " +
			       "desc " + data[i]["description"]);
		}

	}

	// Use this for initialization
	void Start () {
	}

	// Update is called once per frame
	void Update () {

	}
}

See full example code in Github: https://github.com/tikonen/blog/tree/master/csvreader

11 Responses to Lightweight CSV reader for Unity

  1. Sangil Yoon says:

    Thx so much~! it was really helpful. I’ve looked tons of CSVReaders on the internet and I guess this one is most powerful and the smallest in the world

  2. ariff says:

    how do we run and observe the output? since i can’t seem to start the Main.cs with or without debugging. Should we press play in unity? Then where we can see the printed data in example.csv? Please reply. Thank you!

    • tikonen says:

      You don’t understand principles of Unity, please follow basic tutorials before attempting more advanced stuff.

  3. rianluthfi says:

    Thank you for you’re sharing, its very helpful

  4. rianluthfi says:

    Hello may i ask question.
    how you can read CSV from outside unityfile, thanks before

  5. xyzDave says:

    Great bit of code, used it in an app to convert CSV data.
    Minor fix if you are interested – I noticed it wont handle a string containing quotes, especially if the quoted section is at the end e.g. “Hello said \”Bob\””. The trim strips all quotes at the end.
    Add a function:
    public static string UnquoteString(string str)
    {
    if (String.IsNullOrEmpty(str))
    return str;

    int length = str.Length;
    if (length > 1 && str[0] == ‘\”‘ && str[length – 1] == ‘\”‘)
    str = str.Substring(1, length – 2);

    return str;
    }
    then change the inner loop to be:

    for(var j=0; j < header.Length && j < values.Length; j++ )
    {
    string value = values[j].Replace("\"\"","\"");
    value = UnquoteString(value);
    value = value.Replace("\\", "");
    ….

    Seems to work nicely.
    Thanks again for the code.

  6. thanks for writing this mate!

  7. leland says:

    I am currently reading a CSV file which was splitted with semi-colons with the script you provided, but the splitting doesn’t seem to work.
    Could do please drop me a little hint here? thank you !

    • tikonen says:

      The cvs reader assumes comma (‘,’) separated columns. You need to modify the regexp to this:
      “static string SPLIT_RE = @”;(?=(?:[^””]*””[^””]*””)*(?![^””]*””))”;”

  8. Nico says:

    I need to give my players the ability to provide their own CSV file in either the persistentDataPath or the streamingDataPath. Because of this, using Resources.Load(file) is not a possible solution for me. Is there another way to feed your reader a file/file path and it still function? I read it’s impossible to generate a TextAsset at runtime, so maybe a way to deal with a pure string of a csv file. Considering TextAsset.text is a string, would it work if I just replace “data.text” with a serialized version of a file in another file path? Thanks for reading!

    • tikonen says:

      Correct, you can pass string from any source to the Regex.Split as long as it presents a valid CSV data (newline separated lines and comma separated columns.). For example “col1,col2\n1,2\n3,4\n” would be parsed correctly.

Leave a Reply to Nico Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: