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

7 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!

Leave a 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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

%d bloggers like this: