ScriptableObject Tutorial: Getting Started

In this tutorial you’ll learn how to create and use ScriptableObject in Unity. ScriptableObjects in Unity can increase your workflow, reduce memory usage, and even decouple your code architecture. By Ben MacKinnon.

4.5 (45) · 1 Review

Download materials
Save for later
Share

Update May 2019: This tutorial was updated to Unity 2019.1 by Ben MacKinnon. Original post by Jeff Fisher.

ScriptableObject, according to Unity, is an inheritable class that allows you to store large quantities of shared data, independent from script instances.

There are a number of reasons to use ScriptableObject in Unity. They can increase your workflow, reduce memory usage and even decouple your code architecture. You will also lighten the memory usage of each extra prefab instance because, at its core, a ScriptableObject follows the Flyweight design pattern.

Another benefit of ScriptableObjects, which will be the focus of this tutorial, is using them to swap out data with ease. You’ll be doing this by creating a Sword Merchant shop that will display different stats, costs and descriptions for various swords.

In this tutorial, you’ll learn how to create and use ScriptableObjects in Unity.

Note: This tutorial assumes you know your way around the Unity editor. You should know how to edit code in a code editor and have a basic knowledge of C#. If you need to sharpen your Unity skills, check out some of our other Unity tutorials.

Getting Started

Start by downloading the materials you’ll need using the Download Materials link at the top or bottom of this tutorial.

Next, extract the download to a location of your choosing and open up the Scriptable Object Tutorial-Starter project in Unity.

You should see the following folder created as part of the starter project setup:

  • _Setup: For this tutorial, you won’t need to go into this folder at all.
  • Scenes: Contains the Sword Merchant scene that you’ll occupy for the entirety of this tutorial. Make sure you’re in this scene now.
  • Scripts: Currently houses one empty script, but you’ll add more during this tutorial.
  • Sword Icons: Contains thumbnails of each individual sword.
  • Sword Prefabs: Contains a prefab of every sword in the Sword Merchant scene.

Creating a ScriptableObject

First, make sure you are in the Sword Merchant scene. It should look like this:

Setting Up Your ScriptableObject

It’s time to make your first ScriptableObject!

Under the Scripts folder, create a new script called SwordData. This class will be used as a container for all the sword data that will display in your Sword Merchant shop.

Inside this class, start by deriving from ScriptableObject instead of MonoBehaviour:

public class SwordData : ScriptableObject
{

}

This action tells Unity that you still want to use Unity features and methods, like a typical MonoBehaviour, but you’ll no longer need to put this script onto a GameObject. Instead, it will be treated like any other common asset that can be created, similar to creating a prefab, scene or material.

Fill this script with some serialized fields that will contain all the data, corresponding with the information displayed on the Sword Merchant UI.

public class SwordData : ScriptableObject
{
    [SerializeField]
    private string swordName;
    [SerializeField]
    private string description;
    [SerializeField]
    private Sprite icon;
    [SerializeField]
    private int goldCost;
    [SerializeField]
    private int attackDamage;
}
  • swordName: A string to hold the name of the sword.
  • description: A string to hold the description of the sword.
  • icon: A sprite to hold the icon of the sword.
  • goldCost: An int to hold the gold cost of the sword.
  • attackDamage: An int to hold the attack damage of the sword.
Note: SerializeField
In Unity, the SerializeField attribute allows you to have private script variables that are exposed in the Inspector. This will let you set the values in the editor without giving access to the variable from other scripts.

Each sword will need it’s own unique implementation of the SwordData ScriptableObject. But before you can create these implementations, you will need to add your ScriptableObject to the Asset Menu.

Add your ScriptableObject to the Asset Menu by giving the SwordData class the following attribute:

[CreateAssetMenu(fileName = "New SwordData", menuName = "Sword Data", order = 51)]
public class SwordData : ScriptableObject
  • fileName: The default name when the asset is created.
  • menuName: The name of the asset as it appears in the Asset Menu.
  • order: Where the asset will be located within the Asset Menu. Unity separates assets into sub-groups by factors of 50. So 51 will put your new asset in the second grouping of the Asset Menu.

If all went well, you should be able to go to Assets ► Create and see your new Sword Data asset on the menu. It should be located in the second grouping underneath the Folder asset:

Alternatively, you should be able to right click within the Project window and see your new Sword Data asset there as well:

Adding Data

Stay organized by creating a folder under your Scripts folder called Scriptable Objects, and then another folder inside of the Scriptable Objects folder called Sword Data.

Inside the newly created Sword Data folder, create your first Sword Data asset.

The new Sword Data asset should still have the default fileName specified earlier. Select the asset and duplicate it six times (Ctrl/Cmd + D) to create seven total Sword Data assets, one for each of the swords. Now, rename each asset accordingly to match its respective prefab:

Click on the first Sword Data asset in the Sword Data folder, and take a look at the Inspector window:

Here, you’ll see an asset to store information about this particular sword. Fill in the information for each sword. Try to give them all a unique description, gold cost, and attack damage. Be sure to use the appropriate sprites located under the Sword Icons folder for the Icon Sprite field:

Congrats! You’ve created a ScriptableObject and set up various assets using that ScriptableObject.

Using a ScriptableObject

Now it’s time to get the data from these ScriptableObjects.

First, you need to add some public getter methods so that other scripts can access the private fields inside your ScriptableObject. Open up SwordData.cs and add the following under the fields that you added earlier:

    
    public string SwordName
    {
        get
        {
            return swordName;
        }
    }

    public string Description
    {
        get
        {
            return description;
        }
    }

    public Sprite Icon
    {
        get
        {
            return icon;
        }
    }

    public int GoldCost
    {
        get
        {
            return goldCost;
        }
    }

    public int AttackDamage
    {
        get
        {
            return attackDamage;
        }
    }

Open up Sword.cs and add the following code:

    
    [SerializeField]
    private SwordData swordData; // 1

    private void OnMouseDown() // 2
    {
        Debug.Log(swordData.SwordName); // 3
        Debug.Log(swordData.Description); // 3
        Debug.Log(swordData.Icon.name); // 3
        Debug.Log(swordData.GoldCost); // 3
        Debug.Log(swordData.AttackDamage); // 3
    }

Here’s what you’ve added with the above code:

  1. The data container for this sword’s data.
  2. OnMouseDown is a built-in MonoBehaviour function that will be called when the user clicks the mouse.
  3. Examples of how to retrieve the data from your ScriptableObject asset

Return to Unity and go to the Hierarchy window. Select 1_Longsword under the Swords GameObject. Add the respective 1_Longsword data asset to the Sword‘s Sword Data slot:

Click Play in the Unity editor and then click the sword on the far left:

You should see console output resembling the data provided from the Sword Data asset.

ScriptableObjects allow you to swap out this data with ease. Go ahead and put a different ScriptableObject Sword Data in that sword’s Sword Data field.

That was a lot of swords… Here! Have another!