Unity ScriptableObject, When and how to use.

Unity ScriptableObjects are a powerful tool that allow game developers to create reusable and modular data structures. They provide a way to encapsulate and manipulate data in a way that is easy to understand, maintain and share across different parts of a game project. With ScriptableObjects, developers can create and manipulate game objects, data and other assets without writing code, enabling rapid prototyping and iteration. In this article, we will dive into the world of ScriptableObjects, exploring their benefits and how to use them effectively in Unity game development.

Unity ScriptableObject Class

Video Tutorial

What is a ScriptableObject in Unity?

ScriptableObject is a simple class that holds data. You might ask what type of data? Well, it can hold any type of data that you want it to. Then why not create a simple C# script? ScriptableObjects are C# scripts that can be inherited in a simple way. Ok, this little confusing. Now let’s try to understand ScriptableObjects in simple terms with examples.

You have heard about Prefabs in Unity, right? Prefabs are Objects that need to be used more than once in the game and are exactly identical to each other. But what if you need a gameobject that has the same properties but different values. Generally, we create a prefab variant. A better approach to this is to create a ScriptableObject and use them to create the variants. ScriptableObject will hold all the data required for your gameobject variants. You can think of ScriptableObject as a template for your gameobjects.

Still confused? No problem, it will be clear once we see the execution.

Why use a ScriptableObject?

All the data that you store using ScriptableObject is saved as an Asset and is independent of Scenes in Unity. Since they are just data containers, they occupy a very small disk space. They are also good for better memory allocation and performance.

If you create multiple gameobjects with same parameters then it creates a memory slot of each datatype. If you have 1000 gameobjects then it means allocating space for so many variables. But if you use a scriptable object and a gameobject template then you will need to allocate memory only once.

How to create a ScriptableObject in Unity?

Creating a ScriptableObject is very simple. You just need to create a simple C# script inside your project folder. You can do that by right clicking on the Project folder and going to Create>C# script.

Open the script in your script editor and change the inheritance of your class from MonoBehaviour to ScriptableObject.

Here is an example for an empty ScriptableObject script

using UnityEngine;

public class Hero : ScriptableObject
{
   
}

Adding properties and creating Asset menu for ScriptableObject

Let’s create some properties for our hero object. Every hero will have a prefab that’s the model and animation, then Name, Health and Damage.

Also, we need to add an Asset menu option, so that we can create Heros from project window. To create an Asset menu, you can use the CreateAssetMenu reference.

using UnityEngine;
[CreateAssetMenu(fileName ="Hero_features",menuName ="ScriptableObject/Hero")]
public class Hero : ScriptableObject
{
    public GameObject hero_model;
    public string hero_name;
    public float hero_health;
    public float hero_damage;
    
   
}

Let’s Create new object of type Hero ScriptableObject

Now that we have our template in form of a ScriptableObject, let’s create some heroes. Just go to the project window, right click>Create>ScriptableObject>Hero. This option is available because we used CreateAssetMenu reference in our script.

This will create an GameObject of type Hero. You can set the parameter based on your requirement and you have a Hero ready. I am going to create two Heros, Cube and Capsule and assign them different properties.

Now that we have created Heros, what’s next? By now, you should have noticed that nothing happened after creating the Heros. Thats because we need to add them to the scene.

Getting Data from ScriptableObject

Generally, while creating a ScriptableObject class, all the parameters are set to public. For Example, like the Hero class above, has name,health and damage set as public variables. This allows us to access these variables from another script using an object of the Hero class.

You can add in any datatype that you want inside the script and save it. Whether to make them public or private will depend on your game’s design. If you just want to read the data then you can make them private and create small public functions to read the data.

To access the data of the any Hero ScriptableObject, you need to create a variable of type Hero and then assign the ScriptableObject to it. Then you can use the variable to access the public data of the Hero class.

A demonstration of the same is done below. We will try to spawn a Hero ScriptableObject by accessing it’s data.

Spawn ScriptableObject during runtime

Let’s create a template to add in any type of hero that we need. Since the Hero class is a ScriptableObject, you cannot use it directly without a game object. Also, you cannot attach the ScriptableObject to a gameobject. The only way is to use another script.

Create an empty gameobject in your scene and attach a script called Hero_spawn.

In this script, we will take in the data from our Hero ScriptableObject and use them to spawn a Hero.

using UnityEngine;

public class Hero_spawn : MonoBehaviour
{
    public Hero hero_data;
    string player_name;
    float player_damage;
    float player_health;
    

    // Start is called before the first frame update
    void Start()
    {
        player_damage=hero_data.hero_damage;
        player_health=hero_data.hero_health;
        player_name=hero_data.hero_name;
        Instantiate(hero_data.hero_model,transform.position,Quaternion.identity);
        Debug.Log("Player Name: "+player_name);        
        Debug.Log("Player Damage: "+player_damage);  
        Debug.Log("Player Health: "+player_health);       

    }

    
}

Now just assign the different Hero ScriptableObject to the hero_data variable and see them spawn.

Now comes the biggest question. Why not create a prefab with the parameter variants for each Hero, rather than creating ScriptableObjects.

Prefabs vs ScriptableObject

You can very well create prefabs in place of ScriptableObjects but it’s just better structured and more efficient to create ScriptableObjects in some cases.

A prefab with a single script attached can do the same thing as a ScriptableObject, except that it has the extra overhead of having a GameObject and Transform so it takes up more disk space, more RAM, more load time, etc. which is a waste if you don’t actually need any of its features.

So, if you have 100 Heros in your game and all are prefabs then it will take up more disk space than using a ScriptableObject.

Limitations of Unity ScriptableObjects

While Unity ScriptableObjects are a powerful tool for game development, they do have some limitations. One of the primary limitations is that ScriptableObjects cannot be used as components on game objects. This means that they cannot be added directly to game objects like other components, and instead must be referenced from within other scripts or components.

Additionally, ScriptableObjects are not designed to be used for runtime data manipulation. This means that while they can be used to create and modify data structures, they are not ideal for real-time data manipulation or updating.

Another limitation of ScriptableObjects is that they can become difficult to manage if not used properly. Since they are reusable and can be referenced by multiple scripts and components, it can be easy to lose track of how they are being used or modified.

Finally, ScriptableObjects are not a replacement for traditional code-based programming. While they can be used to create complex data structures and even some game logic, they are not a substitute for writing code when more complex game systems are needed.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Tips to create good in-game tutorials 10 key points for a game trailer Why is UX important in Game design? Level Designer’s Role in Game development How to Use Game Analytics?