Sponsored By

Create Scriptable Objects with Unity

The main objective of this blog post is to give you an idea about ScriptableObject in Unity.

Vivek Tank, Blogger

July 16, 2018

6 Min Read
Game Developer logo in a gray background | Game Developer

Objective

The main objective of this blog post is to give you an idea about ScriptableObject in Unity.

 

What is Scriptable Object?

What is the difference between ScriptableObject and Monobehaviour class?

What are Pros and Cons of Scriptableobject?

How to use ScriptableObject?

Let’s undertstand all the questions by taking one ride of this blog about ScriptableObject

According to Unity API documentation,

"ScriptableObject is a class you can derive from if you want to create objects that don't need to be attached to game objects."

Confuesed..?

Don’t worry, if you didn’t get it. Here, I will Explain what it means.

As we know, with Unity, everything is an Object.

Types of Object

Monobehaviours are one of the Objects.

GameObjects: In your scene, you can move around with transform.

ScriptableObject is a kind of Object but, it can only Contain Data.

So, they don’t get involved in the actual game.

I hope you understood the definition of ScriptableObject.

Let's discuss Pros and Cons of ScriptableObject.

Prose of ScriptableObject:

  1. Built into Unity

    • They’re very well maintained by Unity.

    • You can interact with them very easily in Unity inspector.

  2. Can be saved as Assets

    • You can create it as a mini file inside your project.

    • You can update that and save that as per your game requirements.

  3. Can save during runtime

    • If you change something during runtime it will actually remember that.

  4. Internal Solution

    • When you are trying to get the data during run time of the game, you don’t worry about parsing external files which will come into play more.

  5. Large amounts of Data

    • You can save millions of integers inside of a ScriptableObject.

    • So, there’s a lot of space(no size limit function).

  6. Add to Structure as you go

    • As you’re building a scriptable object and create few instances of it and realize ,ohh I need a new setting for ‘moveSpeed’ or whatever additional variable you need you can add, it won’t disrupt your variable.

    • Deleting variable can have a little bit negative impact.

Cons of ScriptableObject:

  1. Requires an editor scripting

    • If you want to make assets out of scripting then you have to know a little bit about it.

  2. Can’t edit outside Unity

    • If you’re working strictly with Unity that’s not really a huge issue.

    • But if you have like team base solution, where you want to send files to someone and have them edit then it won’t work.

  3. Can’t save once deployed

    • Can’t save during runtime,once you’ve built the game meaning that this is not solution for saving a player’s data.This is only for saving game development data.

Let's take one example to understand how to use ScriptableObject in game.

Let me give you one task first.

Suppose, we have 10 level game and at each level the behaviour of enemy will change.

Any Ideas, how you will do this??

Ahh, You might think that make 10 prefab of 10 different enemy and assign it to each level. Right??

Are you sure, it really a good practise?

Actually, the answer is No.

"Because one enemy object may have 4 variable and Update() function with it, and suppose is uses 4 Mb of memory, so 10 level enemy may require 40 Mb of memory amount."

So, here is the solution. Use ScriptableObject to store data of enemy Object.

Let’s, develop our mini game with ScriptableObject.

First, I will create a simple script without using a ScriptableObject. (As per our first thought about creating different prefab of each different enemy and assign it to each level ;) )

Step 1

  • Create an empty GameObject name it Enemy.

Step 2

  • Create C# script and name it EnemyMove

Write following code in EnemyMove.cs


public class EnemyMove : MonoBehaviour {

	#region PUBLIC_VARIABLES
	public string name;
	public int moveSpeed;
	public Color color;
	public string colorName; 
	public SpriteRenderer spriterendere;
	#endregion

	#region PRIVATE_VARIABLES
	private float speed;
	Vector3 newPosition;
	#endregion

	#region UNITY_CALLBACKS
	void Update () {
		ChangeSpeed();
		gameObject.name = name;
		spriterendere.color = color;
		newPosition=transform.position;
		newPosition.y = Mathf.Sin (Time.time) * speed;
		transform.position = newPosition;
	}
	#endregion

	#region PROVATE_METHODS
	private void ChangeSpeed(){
		speed = Mathf.MoveTowards (speed,moveSpeed,Time.deltaTime);
	}
	#endregion
}

Step 3

  • Assign it to empty GameObject(Enemy).

  • EnemyMove script has three public variables.

  • If game has so many enemy GameObject with enemyMove script with it then uses lots of memory.

  • For that as per our solution ScriptableObject, we can make a EnemyData script Instead of storing these variable within EnemyMove script.

Step 4

  • Create C# script name it EnemyData.

  • which inherits ScriptableObject instead of Monobehaviour.

Write the following code in EnemyData.cs.


public class EnemyData : ScriptableObject {

	#region PUBLIC_VERIABLE
	public string name;
	public int moveSpeed;
	public Color color;
	public string colorName; 
	#endregion
}

Step 5

  • Change the code inside ‘EnemyMove’,which was previously created.

  • Create One public variable ‘data’ which is the reference of ‘EnemyData’.

  • Remove the public which is already in ‘EnemyData’

Change according to following code.


public class EnemyMove : MonoBehaviour {

	#region PUBLIC_VARIABLES
	public EnemyData data;
	public SpriteRenderer spriterendere;
	#endregion

	#region PRIVATE_VARIABLES
	private float speed;
	Vector3 newPosition;
	#endregion

	#region UNITY_CALLBACKS
	void Update () {
		ChangeSpeed();
		gameObject.name = name;
		spriterendere.color = data.color;
		newPosition=transform.position;
		newPosition.y = Mathf.Sin (Time.time) * speed;
		transform.position = newPosition;
	}
	#endregion

	#region PROVATE_METHODS
	private void ChangeSpeed(){
		speed=Mathf.MoveTowards (speed,data.moveSpeed,Time.deltaTime);
	}
	#endregion
}

Now you can see that inside the Inspector for Enemy GameObject on ‘Data’ variable will appear,

Any idea..what you suppose assign over here??

Enemymove Inspector window

Follow me...

Step 1

  • Add one line in EnemyData.cs as follow


[CreateAssetMenu(fileName="EnemyData" ,menuName="Enemy Data")]
public class EnemyData : ScriptableObject {

	#region PUBLIC_VERIABLE

	public string name;
	public int moveSpeed;
	public Color color;
	public string colorName; 

	#endregion
}

Step 2

  • Create one folder Game data and do following

Assets enemydata menu item

Step 3

  • Name it as you like.

  • Now, you can see all the variable inside the EnemyData in inspector window, you can change values of variable here.

enemy data inspector window

Step 4

  • Assign this into ‘EnemyMove’ script

assign enemy data to enemymove inspector window

I am sure you got all the answers now.

Conclusion

  • ScriptableObject are really good for the fact that they can break your data into more sizeable chunks.

  • So that you’re not eating up a lot of memory.

  • ScriptableObject is only for development purpose.

Feel free to contact us if you really liked this blog. And don’t forget to share your comments below!

Read more about:

Featured Blogs

About the Author

Daily news, dev blogs, and stories from Game Developer straight to your inbox

You May Also Like