MVC in Unity with Scriptable Objects Part 1
Tags: gamedev, unity3d, mvc
Published: 2019-09-16 10:38:39

Welcome to the first part of MVC in Unity with Scriptable Objects. I'll make this part Scriptable Objects only and it will remain plain and simple. 

First, hear from unity:

> A class you can derive from if you want to create objects that don't need to be attached to game objects.
>
> This is most useful for assets which are only meant to store data.

Then we should ask.

### why?

Scriptable Objects native to unity. It has built-in features to use in the editor.

I like the way you use the unity editor in the development cycle. You could make your own editor tools and default editor tools easy enough to configure. With Scriptable Objects, you could carry it further, make your custom data assets and use it in editor or use as a data container.

![Scriptable Object Sample Usage](https://unity.com/sites/default/files/styles/16_9_s_scale_width/public/2018-10/architect_game_scriptable_objects-2.jpg?itok=M1i7qf19)

The image shown above is a sample usage of a Scriptable Object in unity. A single .asset file created in project file can responsible to carry info to many other system in the game and it persists. There is a great presentation about SO on youtube if you'd like to get more (its name [Overthrowing the MonoBehaviour Tyranny in a Glorious Scriptable Object Revolution](https://www.youtube.com/watch?v=6vmRwLYWNRo) :)) about this.

![Scriptable Objects inventory sample](https://blogs.unity3d.com/wp-content/uploads/2017/11/Screenshot-2017-11-14-12.50.24-1.png)

Another great sample is shown above.  Here other `MonoBehaviour` objects have a reference on Inventory object and Save System has them all. This image is from another great talk, [Game Architecture with Scriptable Objects](https://www.youtube.com/watch?v=raQ3iHhE_Kk), I highly recommend to check out his approach.

Another awesomeness to add is you wouldn't want to use over .json or .xml to over SO once you understand it features. This makes it perfect for a configuration mechanism in unity.

So let's use it in an action. 

```c#
using UnityEngine;

public class ItemData : ScriptableObject
{
    public string itemName;
    public ItemType type;
    public float attack;		
}

public enum ItemType
{
    Dagger,
    Axe,
    Sword,
    Staff
}
```

We have created a class named `ItemData` and some attributes like in rpg games. We'll make some item in project folder and access them from a script to display on console. But before that, we have add a crucial ingredient to our `ItemData` class.

```c#
using UnityEngine;

[CreateAssetMenu]
public class ItemData : ScriptableObject
{
    public string itemName;
    public ItemType type;
    public float attack;		
}

public enum ItemType
{
    Dagger,
    Axe,
    Sword,
    Staff
}
```

`CreateAssetMenu` attribute is we have added on `ItemData` class is specifying to unity that we want to create a file in project folder from this SO class, otherwise, you can't create .asset file from the editor with right-click or use create button in the project folder.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/5ovncrjzyvuaxtofqncu.png)

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/d8njgbircw7k10ioi3b1.png)

Let's create a folder named `Items` and try to create an `ItemData` in the project folder.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/pb0e73au9u2tdfcs0j1p.png)

I'll make another script to hold these data files named `Inventory`.

```c#
using UnityEngine;

public class Inventory : MonoBehaviour
{
    public ItemData[] inventory;
}
```

Add a method to display item info on console and length control to inventory.

```c#
using UnityEngine;

public class Inventory : MonoBehaviour
{
    public ItemData[] inventory;
    
    int index = 0;

    public void NextItemInfo()
    {
        if (index > inventory.Length)
        {
            index = 0;
        }

        Debug.Log("Item name: " + inventory[index].name);
        Debug.Log ("Attack power: " + inventory[index].attack);

        switch(inventory[index].type)
        {
            case ItemType.Axe: 
            Debug.Log("Item type: Axe"); 
            break;

            case ItemType.Dagger: 
            Debug.Log("Item type: Dagger");
            break;

            case ItemType.Staff: 
            Debug.Log("Item type: Staff");
            break;

            case ItemType.Sword: 
            Debug.Log("Item type: Sword"); 
            break;
        }

        index ++;
    }
		
}
```

I'll use the space bar to use our method. It very easy makes it with unity. In `Update` we'll check if our key pressed, thanks to `Input` class.

```c#
using UnityEngine;

public class Inventory : MonoBehaviour
{
    public ItemData[] inventory;
    
    int index = 0;

    private void Update() 
    {
        if (Input.GetKeyDown(KeyCode.Space))    
        {
            NextItemInfo();
        }
    }
    
    public void NextItemInfo()
    {
        if (index > inventory.Length)
        {
            index = 0;
        }

        Debug.Log("Item name: " + inventory[index].name);
        Debug.Log ("Attack power: " + inventory[index].attack);

        switch(inventory[index].type)
        {
            case ItemType.Axe: 
            Debug.Log("Item type: Axe"); 
            break;

            case ItemType.Dagger: 
            Debug.Log("Item type: Dagger");
            break;

            case ItemType.Staff: 
            Debug.Log("Item type: Staff");
            break;

            case ItemType.Sword: 
            Debug.Log("Item type: Sword"); 
            break;
        }

        index ++;
    }
		
}
```

Now, It's time to switch back to unity editor. We'll populate our `inventory` array with our `ItemData` files that we have created in `Items` folder. But first, let's create an empty object in the scene and attach our `Inventory` script.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/osgifbcap19vetyt1e4w.png)

Let's give it a go. Hit play to test it.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/744ibudz5gful8lkx4jz.gif)

It's working! Now I want to want to show you that you could not only carry variables in SO, but we'll also add a method to calculate the price for us in `ItemData` . Look up in docs to more in [here](https://docs.unity3d.com/ScriptReference/ScriptableObject.html) and [here](https://docs.unity3d.com/2018.3/Documentation/Manual/class-ScriptableObject.html).

```c#
using UnityEngine;

[CreateAssetMenu]
public class ItemData : ScriptableObject
{
    public string itemName;
    public ItemType type;
    public float attack;		

    public float GetPrice()
    {
        return attack * 40;
    }
}
```

Then in `Inventory` let's use our new method :

```c#
using UnityEngine;

public class Inventory : MonoBehaviour
{
    public ItemData[] inventory;
    
    int index = 0;

    private void Update() 
    {
        if (Input.GetKeyDown(KeyCode.Space))    
        {
            NextItemInfo();
        }
    }
    
    public void NextItemInfo()
    {
        if (index == inventory.Length)
        {
            index = 0;
        }

        Debug.Log("Item name: " + inventory[index].name);
        Debug.Log ("Attack power: " + inventory[index].attack);

        switch(inventory[index].type)
        {
            case ItemType.Axe: 
            Debug.Log("Item type: Axe"); 
            break;

            case ItemType.Dagger: 
            Debug.Log("Item type: Dagger");
            break;

            case ItemType.Staff: 
            Debug.Log("Item type: Staff");
            break;

            case ItemType.Sword: 
            Debug.Log("Item type: Sword"); 
            break;
        }
        Debug.Log("Item price: " + inventory[index].GetPrice());

        index ++;
    }
		
}
```

Now hit the play to see the result.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/bivnekdo4yacrqxc2q6c.png)

Check out unity project on [github](https://github.com/cemuka/intro-to-so)!

This was the end of our first part. Next part we'll introduce the MVC in unity. But since we are familiar with the SO, we'll add some SO spice to make it more robust and this is how unity ninja's do 😎👾