ScriptableObjects are a special kind of script that is designed specifically to hold different types of data. Unlike traditional C# scripts, ScriptableObjects do not need to be, and in fact, cannot be, directly attached to GameObjects. In this tutorial, you will learn about ScriptableObjects and how to use them.
ScriptableObjects are a special kind of script that is designed specifically to hold different types of data. Unlike traditional C# scripts, ScriptableObjects do not need to be, and in fact, cannot be, directly attached to GameObjects. The reason for this is because ScriptableObjects are never tied to any one single object. Instead, the information they contain can be shared with any object and are easily accessible via other scripts. This makes ScriptableObjects ideal for sharing information between objects.While ScriptableObjects are not necessarily an advanced subject, understanding when and where they should be used can be. To learn about ScriptableObjects in more detail and understand why they are so helpful, please refer to this blog post about ScriptableObjects: Making Cool Stuff with ScriptableObjects and this Unite Talk: ScriptableObjects: What they are and how to use them.
ScriptableObjects are excellent for projects that handle a lot of data that might change throughout production. The example below is a ScriptableObject that defines components for a kitchen. (fig 01)
This ScriptableObject contains five different values that can be customized to describe the type of object its defining. Any object in the Kitchen Configurator that can potentially contain drawers can access this ScriptableObject and get all of the information it needs to define the drawer option to the end user. With this drawer example, the script accessing it would be able to tell:
That it’s looking at Drawers (based on the Component Type value: Other values in this dropdown list include Appliance, Countertop, Doors, Surface, and Accessory)
That these drawers can only be styled with Wood Materials (Material List)
That these drawers have multiple style options (Has Swappable Mesh)
That they must always be visible to the object they’re applied to (Visibility Option)
That they do not have an accessory category (Not a Component Type of Accessory, and have Accessory Type set to None)
Using these values as definitions of an object’s appearance, designers can use the same ScriptableObject template to create data for virtually any kind of kitchen object. Below is the same ScriptableObject configured for a backsplash. (fig 02)
The features of this object are immediately very different, even though the same data points are being used. Any script accessing this ScriptableObject would know:
It is looking at a Surface
This backsplash could be configured with Paint, Granite, or Tile material types
It has no other style options
It must always be visible on the wall
It isn’t an accessory
Perhaps the most valuable aspect of ScriptableObjects is that they can be reconfigured at any time, and the changes will be propagated across to anything that is referencing it. For example, if the designer later decided that the backsplash really should only be shown with tile, the Material List option could be changed to reflect this, and all objects referencing the backsplash would automatically know.
The process of creating a ScriptableObject is virtually identical to creating any other script in Unity.
In the Project window, right click and select Create => C# script.
Give the script a descriptive name, ideally indicating that its a ScriptableObject.
Double click the script to open it up in Visual Studio. (fig 03)
By default, all scripts in Unity are created as MonoBehaviours, which is the base class that gives programmers access to Unity’s API. ScriptableObjects are their own type of class, so the script must be updated to reflect the fact that it is a ScriptableObject.
Replace the word MonoBehavior on line 5 with ScriptableObject
Delete the void Start and Update methods, being sure to get the associated brackets. This would be lines 8-15 in the reference above (fig 04)
The ScriptableObject is now properly configured and is ready for any data that you might need to store. Any variable type can be used, but note that if you plan to reference GameObjects, they must be Prefabs, as ScriptableObjects cannot reference any scene object.
For the sake of this example, we will create a simple food object.
On line 6, type: public string foodName;
On line 7, type: public int totalCalories;
On line 8, type: public bool needsCooking;
The final script should look as it does in the example below (fig 05).
At this point the ScriptableObject is usable, however, we want to be able to use this template object many times and it would be convenient to be able to create it in the same way a C# script is created.
Directly above the public class line, type: [CreateAssetMenu(menuName = "Create new food")] (fig 06)
Save the script and return to Unity.
Right click in the project window and in the Create menu; you will now see an option to Create new food. (fig 07)
Click create new food, and name the object Bacon.
Select the Bacon, and in the Inspector, fill in the details that the variables were created for. (fig 08)