ScriptableObjects as they are somewhat built for this purpose.
Benefits
-
Less persistence between scene requirements (using Do Not Destroy and Singletons) which means less worries about potential bugs in complex systems.
-
They are lightweight and a great way to compartmentalize data that can then be serialized to a binary file (or whatever you prefer to do).
Drawbacks
- ScriptableObject data is not reset in the Unity Editor. This an be annoying sometimes. Imagine this scenario:
You store data for the Player’s XP. When testing a new feature you do something that increases this value from “0” xp to “10” xp. When you stop playing the game the data will persist so you would need to reset this to “0” again (or use a script that sets defaults when you play the game)
- Somewhat ironically they do reset when on a build (PC/Android etc). This means that they act more like containers that need data put into them when the player loads the game.
Example: A player starts with 0 experience and gains 10 experience when playing the game. Whilst the game is playing the ScriptableObject data will stay at 10 but when they close the game it will go back to 0.
When they load the game again, you would need to deserialize a binary file and unpack this information back into the scriptable object so they can continue at “10” experience.
Other Stuff
One of the benefits of ScriptableObjects is their flexibility. For example, image you need to represent an integer. However, you might need:
- an integer that represents the players current health
- an integer that represents how many items the player is carrying
- an integer that represents the players current xp level
using UnityEngine;
[CreateAssetMenu(fileName = "GenericInt", menuName = "SO/Generic/Int", order = 1)]
public class GenericIntSO : ScriptableObject
{
public int value;
}
So now you have this generic integer that can be used to represent multiple things and you can use them anywhere else by referencing them in a script.
using UnityEngine;
public class Example : MonoBehaviour
{
public GenericIntSO playerHealth;
public GenericIntSO playerXP;
public GenericIntSO playerInventorySlotsAvailable;
}
So you could have an SO for different types of inventory items
using UnityEngine;
[CreateAssetMenu(fileName = "InventoryItem", menuName = "SO/Core/Inventory/Item", order = 1)]
public class InventoryItemSO : ScriptableObject
{
public int itemID;
public string itemName;
public string itemValue;
}
You could use that as a generic inventory item template that lets you create all of the possible items using a single class and keep a list of SOs.
using UnityEngine;
public class Player: MonoBehaviour
{
public List<InventoryItemSO> playerInventory;
}