I'm moving from an old game dev tool to Unity, and wondering how to go about handling external data files.

In my previous program I'd set up external (txt/ini) files like this:



Then I would simply reference which group name and line I wanted to pull.

What's the equivalent to this in unity? I see I can import TextAssets but I can't find functions to pull select data from it. Do these exist?

Do I have to split by lines, loop through them all and convert it into groups (lists) manually? What is the standard method for doing this? Is it moving to xml files?

  • \$\begingroup\$ Does the file have to be external? This looks like something you could do with a ScriptableObject with a nicer editing interface. As for methods to manipulate text files, you have all of C# at your disposal. So if someone's already written a parser for the text file format you're using, you can just include and call that. \$\endgroup\$
    – DMGregory
    Jun 24, 2020 at 10:54
  • \$\begingroup\$ Do they need to stay in that format? I like JSON and use assetstore.unity.com/packages/tools/input-management/… \$\endgroup\$
    – jhocking
    Jun 26, 2020 at 0:49

1 Answer 1


It's generally better to use ScriptableObject assets rather than text files.

For example,

[CreateAssetMenu(fileName="Level Data", menuName="Level Data")]
public class LevelAsset : ScriptableObject {
    [Range(60, 300)]
    [SerializeField] private float duration;
    [Range(1, 20)]
    [SerializeField] private int obstacles;

    public float Duration => duration;
    public int Obstacles => obstacles;

This adds a new entry called "Level Data" to the "Create" menu (right-click in the Project panel and choose Create, or go to Assets > Create in the menu. Selecting this entry will create a new asset file which you can edit in the Inspector.

enter image description here

You can create as many assets of this type as you wish, and reference them from your scripts.

The GUI-driven interface in the Inspector is safer and easier to use than manually created text files. As you can see in the example, it's type-safe and you can even apply constraints such as [Range()]. When needed, you can even create your own Editors which override the default inspector appearance.

  • \$\begingroup\$ A closer analogue to OP's case might be to define a struct that has a name string and a string array, and have the ScriptableObject hold a list or array of those. If you like, it could digest the structs into a dictionary keyed by the name on initialization/deserialization, to client code can ask for 'the third string of group "foo", please!' \$\endgroup\$
    – DMGregory
    Jun 25, 2020 at 22:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .