Unity simple but type-safe CSV lib

· by Steve · Read in about 3 min · (475 Words)

Recently I found myself wanting to expose a bunch of game parameters for our latest game project to my wife so she could easily edit them, to play with the difficulty and feel of it. I didn’t want her to have to use Unity, I just wanted her to be able to edit a simple file (while the game is running in this case).

Bring on the text

Although Unity’s own JsonUtility is a very useful tool for text exchange, JSON isn’t very approachable for a non-developer, given its very strict syntactic requirements. I also didn’t want to have to spend time on adding a big debug UI.

CSV was perfectly suited, since Marie could edit the settings in a spreadsheet and it would do all the quote-on-embedded-comma stuff for her. Nice and simple for both of us, just the way I like things 🙂

CSV libs too big or too small

So I did a quick trawl of the internet looking for existing solutions. I came across of a lot of threads asking for this, but the most commonly linked solution was CSVReader on the Unity Wiki; while fine I wasn’t keen on how it did quite a lot of allocation just to return string arrays in the end, leaving all the parsing still to do.

At the other extreme were libraries like CSVHelper, which are far more sophisticated but massive and vastly overcomplicated for what I needed.

All I wanted was something that behaved like JsonUtility but for CSV (flat objects only, no nesting); type-aware and doing all the parsing for me, and preferably no more than a couple of files. I didn’t find one. 😞

So I wrote my own: CsvUtil

Here’s my solution to the problem: CsvUtil. 🚢

It supports single-object CSV with one row per field, or multi-object CSV with one row per instance. It supports at least string, int, float, Enum (named value translation) fields, but can pretty much support anything that has a TypeConverter from string and implements ToString. And it’s less than 250 lines of code in a single file (plus tests). 👍

Here’s a quick example of the multi-object workflow; there’s much more detail in the README.md:

Input CSV:

Name,Level,Dps,ShirtColour,#Notes
Steve,20,1002.5,Red,Probably OP
Batman,12,600.6,Black,Who are you
Peewee Herman,1,-2,Purple,wat

(Columns with a # prefix are ignored)

Code:

public class MyObject {
    public string Name;
    public int Level;
    public float Dps;
    public enum Colour {
        Red = 1,
        Green = 2,
        Blue = 3,
        Black = 4,
        Purple = 15
    }
    public Colour ShirtColour;
}
...
List<MyObject> objs = Sinbad.CsvUtil.LoadObjects<MyObject>("file.csv");

It’s pretty easy to use I think and has worked well for our purposes. As well as the documentation the project includes tests which serve as additional examples, plus they will appear in Unity’s Editor Tests Runner window if you use that.

I hope that helps someone else! 🎁