In our game, there is some data that needs to be reachable from outside a scene file, but still about a scene file. For example, on a level select screen, I need to know the names and descriptions of all our levels. Storing this data inside the scene file isn’t an option because you can’t reach it without loading up the level!
So, how have others gone about storing data like this? Our current solution is to use a text file containing this information and then parse the information when the game runs. However, this is pretty messy and error-prone.
3 Answers
3
I’d personally just stick the info in an XML file. If you want it pre-parsed and Unity-ish, though, you can use a ScriptableObject subclass. ScriptableObject is basically a way to make custom assets that are not components. Give it an array of serializable scene-data objects (including name) and keep a reference to it in whatever needs to access the data.
You could just do the simple route. Make a prefab that every scene includes with tables that you set up in the prefab.
// Main class, put this on your prefab as a script
// modify levels through the prefab
public class LevelManager : MonoBehaviour
{
public LevelInfo[] levels;
public string GetDescription(string name)
{
foreach (var info in levels)
if (info.name == name)
return info.description;
}
}
// Helper class used to pair description to name
// and to make it easier to modify using standard
// inspector controls.
[System.Serializable]
public class LevelInfo
{
public string name;
public string description;
}
You could then tag it, or look it up by name when you want to access it.
var manager = GameObject.Find("LevelManager").GetComponent<LevelManager>();
var description = manager.GetDescription("Jungle");
// Do something with description...
You could probably agree on a naming or tag convention and have the level manager provide static methods that do the job for you. With a little thought, you could also have a runtime check to see if the current level has a description and give you a warning in editor only, to set that description. You can exclude the runtime test code (since it has no post-production value) using #if UNITY_EDITOR.
Do you need the data to be available between instances of running the game (i.e. saved to disk?). If so, the playerPrefs documentation is what you want to look at.
For simply saving data between scenes, I create a partially static partially dynamic script that I apply DontDestroyOnLoad to. Some data is kept statically so that it can be accessed without a reference to the gameObject containing the script, and some needs to by dynamic so scripts that use that have to get a reference to the script, and you can use GameObject.Find for that.
Best of luck.
Thanks for all the comments and options. Chose this as the answer because in hindsight, this is ultimately the direction I wish we had gone for ease of use ;). A simple text/XML document that doesn't have the overhead of a prefab/monobehavior is probably best. Minor note, we are on mobile and using the mono XML functionality. This has worked pretty well for us (despite Unity's suggestion to avoid it due to filesize bloat). However, keep in mind the XML library linked in the Unity documentation if you need a lightweight solution.
– kromenak