Good practices for storing readonly data in Unity

Viewed 1787

I'm making a visual novel and my game uses some custom classes that store important data.

Example:

public class Speech
 {
     public Sprite CharacterHead; // Holds a reference to a sprite which is the "head" of who's currently speaking 
     public LocalizedString SpeechOrigin; // Holds a reference to a localizedstring that is what that character is saying based on the language. (Uses Unity.Localization)
     public string Name; // the name of the character that is speaking
 }

This "Speech" class should never be changed during runtime and only needs to be read during dialogues.

My question is: what is a general good-practice way to store this type of data? I'm fairly new to unity and the only way i found to do this yet is through declaring a List on monobehaviour classes and editing them through the Inspector but this does not seems to be a effective way of handling this in a game that's going to have 1000+ different "Speech".

Ps:Don't mind all the variables being public, they are this way right now to make some parts of development easier, i will change the necessary ones when the time comes.

3 Answers

Why don't you just use ScriptableObject? It's the default way for Unity to store data in the game. You can also edit it from the Unity Editor instead of using another external editor. You can also drag-and-drop any resource from the game project's folder into it (eg. the texture of the head, the whole localized sting as data, the dialog audio clips, etc)

https://docs.unity3d.com/Manual/class-ScriptableObject.html

https://youtu.be/aPXvoWVabPY

You should not store a lot of data in c# code use external files that are designed for data by creating a JSON file, XML file, or any other type of both human and computer readable format.

XML should be the perfect choise for your usecase, it is widely used for dialogue trees

Here is an example of what you can do with XML in your usecase

<npcs>
  <npc name="Oren">
    <dialogue>
      <text>Hi #{PlayerName} do you want to eat falafel? </text>
      <options>
        <option action="yes">yes, I would like</option>
        <option action="no">no...</option>
      </options>
    </dialogue>
  </npc>
</npcs>

it's fairly simple to use XML, and it fits dialogues perfectly

There are a few good ways to store this information, especially if you are localising them too. Essentially, you would store an ID that you refer to the various strings with, which would be constant across language files.

  1. CSV format files

Basically, you can use some spreadsheet software (like Google Sheets) and have all your speech there; a column for the ID of the string, and a column for the actual value. You can export the sheet as a CSV file and load into Unity. You can then write some simple parsing code to read each line from the file, and split out the ID and the value and store it in a dictionary.

  1. JSON format files

With JSON, if you architect it correctly, you can use Unity's built in JSON utility, or other better ones, to read the data directly into C# object classes. A decent video explaining this can be found here.

  1. YAML format files

YAML is basically the same as JSON, but with less brackets. It is also the format that Unity uses for its serialisation. However, you can only use this format by writing your own parser, or using a third party one, because there is no built in parser.

JSON files are generally industry standard for data storage these days, but eventually it is up to you which format you find easiest to work with. I've tried to list these in the order of how easy it is to add and remove strings from the file.

Related