Scriptable Objects in Unity3D – Creating a holder for game level for simple board tile based game.

In this tutorial we will create a simple level holder for a board tile based game and construct a level from the holder object.

 

Suppose we have a game that consists of a square board (like Flow) and multiple different elements. In our case elements will be small and large cubes and spheres.

Before starting this tutorial you might want to look at the following articles:

 


(In this article file and directory names from Unity are formatted like this – MainGameScene, class and method names are formatted like this – GameLevelHolder)
When editing the particular level all the information about the level will be immediately stored into .asset file. For this purpose we use Unity3D Scriptable Objects which are most useful for assets which are only meant to store data.
Let’s assume our level will be a square board consisting of different elements of different colors. For instance size can be 3×3, 4×4, 5×5.

Create new Unity project. Save the scene, name it MainGameScene. Make the following folder structure for convenience:

We will have board tiles of different types and colors, so lets create folder called Enums inside Scripts folder and create two enums representing tile type and tile color.


Now let’s create a class that will represent a single tile of our board and a class representing level of our game. We have to make our tile Serializable for it to be displayed in the Unity inspector the same way other Unity objects are (e.g. Vector3)

As you can see GameLevelHolder inherits from ScriptableObject which allows us to save GameLevelHolder objects as .asset files. Let’s also create a custom MenuItem to create a holder for our game level any time we need to. We will store our game levels inside Resources/Levels directory for convenience. CreateGameLevelMenuItem.cs creates an instance of GameLevelHolder, initializes the list of tiles and saves it as an .asset file that represents our game level.

Now we can test our game level creation menu item.

After clicking on our custom menu item a new file inside Resources/Levels directory should appear. The first step is done – now we have a container to store a game level. We will able to make changes to this file through the wizard GUI. When playing a game we will be able to read this file and build the level using this .asset file. 

Now let’s read this level we have just created. Create a static class Utils which will provide us a method to retrieve our newly created level. Change “Level Name” field to “First Level” in the inspector tab.

Now let’s create the class that will construct our game level using the info retrieved from the .asset file. Let’s name this class BoardConstructor and retrieve our game level inside Start() method. Also create an empty GameObject, reset its transform and drag the BoardConstructor script onto it. Now rename it to “pref_BoardConstructor” and drag into the “Prefabs” folder.

You can now press “Play” button and have a look at the Console tab. If you have done everything right you should see the name of our game level displayed there.

We have successfully read the level so let’s try to use our BoardConstructor to create it’s visual representation.

First we need to prepare prefabs which our board will consist of. Create the following GameObjects and save them as prefabs inside Prefabs/BoardElements directory (reset each element position to 0, 0, 0):

  • A cube with scale (1, 1, 0.1) and name it pref_BoardFoundation
  • A cube with scale (0.7, 0.7, 0.7) and name it pref_CubeLarge
  • A cube with scale (0.3, 0.3, 0.3) and name it pref_CubeSmall
  • A sphere with scale (0.7, 0.7, 0.7) and name it pref_SphereLarge
  • A sphere with scale (0.3, 0.3, 0.3) and name it pref_SphereSmall
Also create a black material named mat_Foundation and assign it to pref_BoardFoundation. Now let’s update our script so it could construct the board from our NewGameLevelHolder.asset file.

 

The script looks big but there is nothing complicated in it. First we declare public Transform variables to be able to set them in Inspector tab. After this we declare dictionaries with element types and colors for convenient access to prefabs and Color values and initialize them. After this we construct our board using information read from NewGameLevelHolder.asset file.

Drag and drop element prefabs created before to corresponding empty slots of BoardConstructor script.

After you finish the script and drag-and-drop prefabs press “Play” button and you will see the simple board constructed. The result should look like this (depends on your changes in the .asset file, here I’ve changed some colors and element types):

Now try to edit level file and change element types and colors. Press “Play” button again and you will see that your updates are visible after the board is constructed.

So we now we have constructed a board using information that was read from the .asset file.

 

This shows how Scriptable Objects can be useful when you need to store object data.

Download zipped Unity3D project. Please leave comments if you have any issues.