Oftentimes, we ask ourselves the question, how do we want to store data in Unity?
There is a high probability that you wanted to create a database and make it editable with ease for either a developer or a designer. There are a lot of ways of dealing with this problem, but the way we want to tackle this today is the most friendly from a Unity design perspective.
This is also an automated way for developers to work with designers, thanks to the runtime data reading process along with looping through a resources folder. The best part of this solution is – it does not require additional plugins.
The other important aspect of this solution is the way in which we interact with the data later on. All items are stored in the collection and are easily accessible through a user-defined key.
This solution can be used for many different cases. I personally have been using it in systems like holding items or skills data for my RPG game.
This is a great way to hold data as it’s simple and robust, especially with multiplayer games. The data objects are indexed and can be easily exported to json from scriptable objects.
Warning: When serializing to json, take care over what fields you put in the data scriptable object class. Not every field can be serialized (ex. Sprite, GameObject, Transform).
There are 4 main scripts in the project we are going to use, and they are explained in the further sections.
ScriptableObjects System allows you to store data in Unity Engine as an asset in the folder.
This asset can be read and modified in the game from the code level, although it’s not recommended to modify the ScriptableObject on the runtime from the code level. Its purpose is to store the data, not to hold temporary variables.
The big advantage is it can be assigned in the editor in an exposed variable.
Warning: In the editor, changing the ScriptableObject fields from the code level on runtime can cause weird behaviour in the Editor. It’s data is going to remain the same after we stop the game, but if we don’t set it as Dirty in the editor, it will go back to its original state at some point.
Creating Object Data (Scriptable Object)
Scriptable Objects can be added through classes, which derives from ScriptableObject class and is marked with the [CreateAssetMenu(menuName=path)] attribute. Based on the menuName parameter in the attribute, we will be able to create the item ScriptableObject in the Create section. After we add this script, and after Unity recompiles the scripts, the option to add a data object will appear after right clicking on the selected folder in the project window.
Now simply fill out the variables for the item data object and the item is ready to use!
Reading the Data from Resources and initializing the database Resources folder in this solution acts as a database container.
Now, if we have created the data container, we need to create a script which will contain a collection of each individual data object. Every ScriptableObject under the Items folder, will be loaded on the initialization.
This manager derives from the DataManager with two generic arguments for the index and data type. It contains methods to put and remove the items with additional logical checks.
In order to read the items from a Resources folder, we will use the Resources.LoadAll<T>(string); method.
This will return an array of items and, later on, we can assign it into the indexed dictionary collection.
Using the database in a test inventory context
Now we just need to create the two empty GameObjects and assign ItemDataManager.cs and InventoryTestContext.cs components.
The InventoryTestContext component needs to reference the ItemDataManager in order to initialize and obtain data from it.
Once the initialization is done, it can be used to get the data objects. This is done by the InventoryTestContext script.
After we start the Game, this script will print all of the items from the referenced itemsDataManager.
As you can see, with a little effort at the beginning of the development, we can create expandable and structured databases for later usage without any issues.
Data Objects from Resources are loaded dynamically from the folder which is pointed in the script variable and are initialized whenever the developer calls it from any context.
This solution can be applied to any type of data and will make your life easier!
Make sure to check out the unity package file provided below. It will show
you the entire solution and structure which we consider proper for the Unity projects.
Let us know how you like the solution below!