Unity Scriptable Object tutorial, When and how to use.

Unity Scriptable Objects 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 Scriptable Objects, developers can create and manipulate game objects, data and other assets without rewriting code. In this article, we will dive into the world of Scriptable Objects, exploring their benefits and how to use them effectively in Unity game development.

Unity ScriptableObject Class

Video Tutorial

What is a Scriptable Object in Unity?


In Unity, Scriptable Objects are a powerful feature that allow developers to create custom data container to store and manage game-related information. These objects are essentially assets within the Unity engine, stored in the project window, and can be used to save data that can be easily accessed and shared across different scripts, objects, and scenes.

Then why not create a simple C# script? Scriptable Objects are C# scripts that can be inherited from in a simple way. Ok, this little confusing. Now let’s try to understand them 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 an object that has the same properties but different values. Generally, we create a prefab variant.

A better approach to this is to create a Scriptable Object. It will hold all the data required for your object variants. You can think of it as a script template to store data for your game objects.

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

Why use Scriptable Objects?

All the data that you store using Scriptable Object 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.

One of the main benefits of using them is that they can store large quantities of specific data without the need to create instances of script variables or objects. This helps reduce memory usage and optimizes the performance of your game.

How to create a Scriptable Object in Unity?

Creating a Scriptable Object is very similar to creating a new script in Unity. Actually, you just need to create a simple C# script inside your project view. You can do that by right clicking on the Project window and going to Create>C# script.

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

Here is a simple example for an empty Scriptable Object script

using UnityEngine;

public class Hero : ScriptableObject
{
   
}

Create Menu and Add Properties

Let’s create some properties for our hero class that we created above. Every hero will have a prefab that’s the model and animation. Then each Hero will have Name, Health and Damage properties.

Also, we need to add an Asset menu option, so that we can create Heros from project window. To create menu in Unity Editor, 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

Now that we have our template in form of a Scriptable Object data, 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 a Game Object of type Hero. You can set the parameter based on your requirement in the inspector window 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. That’s because we need to add them to the scene.

Getting Data from Scriptable Object

Generally, while creating a Scriptable Object 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 in play mode 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 scriptable object’s data, you need to create a variable of type Hero and then assign the Scriptable Object 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 Scriptable Object by accessing it’s data.

Spawn Scriptable Object during runtime

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

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

In this script, we will take in the data from our Hero Scriptable Object 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 Scriptable Object to the hero_data variable and see them spawn.

Now comes the biggest question. Why not create a prefab variants for each Hero.

Prefabs vs Scriptable Object

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

A prefab with a single script attached can do the same thing as a Scriptable Object, except that it has the extra overhead of having an Object 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 large amounts of data compared to using a Scriptable Object.

Limitations of Unity Scriptable Objects

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

Additionally, they 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 Scriptable Objects 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.

Other main use cases

The best example of how Scriptable objects can be used is the Inventory system. Additionally, Scriptable Objects can be used in conjunction with Game Events to create a flexible event-driven system. Game Events (represented by the class GameEvent) are custom events that can be raised in the game to trigger specific actions. They can hold unique data, such as a specific game event identifier or additional parameters.

To respond to a Game Event, you can use a Game Event Listener (represented by the class GameEventListener). This listener script can register itself to listen for specific Game Events using the RegisterListener method.

When the registered Game Event is raised, the OnEventRaised method is called in the listener, allowing you to perform the necessary actions or update the user interface based on the event’s data. This is a complete tutorial of its own so we will cover it separately.

Scriptable Objects provide a flexible way to store and manage game-related data. They reduce memory usage, allow for easy sharing and modification of data across different scripts and game objects, and enable the creation of event-driven systems. By using Scriptable Objects effectively, you can optimize your game’s memory usage, enhance modularity, and create a robust and scalable architecture.

Leave a Reply

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

Discover more from VionixStudio

Subscribe now to keep reading and get access to the full archive.

Continue reading