Creating Interactive Game Shops with Unity and Contentful
Prerequisites
You will need the following in order to complete this guide:
Note: This tutorial will be using Visual Studio 2022 since this is what ships by default with Unity. But any other IDE suited for C# development will work.
Creating content types in Contentful
Content types are an integral part of Contentful. They are a model of your content. These are the equivalent of structs or classes within C#. Building games by leveraging Contentful encourages a data-first approach to planning which allows you to easily integrate your content into a game.
While logged in, navigate to Contentful and create a new space.
1. Game Item
We will need to define the data a game item will contain.
Create a content type named Game Item. Then add the following fields:
- Title (Short text): The title of the game item (We want to avoid using Name, as this is a reserved word inside of Unity)
- Strength (Integer): This is an in-game stat
- Defense (Integer): This is an in-game stat
- Speed (Integer): This is an in-game stat
2. Shop Item
Next, we need to create a content type that will hold data pertaining to the game item within the shop.
Create a content type named Shop Item. Then add the following fields:
- Title (Short text): This is the title that will be displayed on the shop card
- Description (Long text): A description about the item
- Price (Integer): How much the item will cost
- On Sale (Boolean): Let the player know if the item is on sale
- Game Item (One reference, that only accepts the Game Item content type): The actual game item
3. Shop Container
Lastly, we need to create a container to hold all of the shop items. These containers will be how we retrieve all of our shop data in-game.
Create a content type named Shop Container. Then add the following fields:
- Title (Short text): Name of the shop
- Highlight (Many References in content model that only accepts the Shop Item content type): The highlight section of the store
- Shop Items (Many References in content model that only accepts the Shop Item content type): The rest of the in-game shop’s inventory
Creating entries in Contentful
Entries are instances of the content. Similar to how ScriptableObjects are based off of a class defining the data, entries are based on content types within Contentful.
Create a few different Game Items. Ensure all of the fields are filled out.
Then, for as many Game Items you have, create the same amount of Shop Items. Don’t forget to link your Game Item!
Finally, create one Shop Container and link every Shop Item you’ve created in either the Highlight or Shop Items field.
Creating the Unity project
New project
From the Unity Hub click on “New Project.”
Verify that your Editor Version is 2022.3.15f1 or later.
Select the “3D Core” template.
Give your project a fun name and click “Create Project.”
Install Contentful CSharp library
There are many ways to install Nuget packages in Unity.
Go to https://www.nuget.org/packages/contentful.csharp
Select “Download Package” in the sidebar.
This will download a .nuget file, which is just a fancy zip. (More info)
Use your file unpacker of choice (WinRAR, 7zip, etc.).
Extract the lib folder.
Create a Libraries folder in your Unity Assets, add your contentful.csharp.<VersionNumber> folder.
Setting up a connection to the ContentDeliveryAPI
One of Contentful’s most powerful features (among many) is our globally distributed CDN, known as the Content Delivery API (CDA). This prioritizes servers closest to your players, minimizing latency as well as improving overall availability of content. Using the Contentful CSharp library we just downloaded allows us to easily tap into the CDA.
Obtaining the credentials
In the upper right hand corner of Contentful there is a Settings dropdown. Click on Settings and then select “API keys.”
For this guide, we will be creating our own API key. Click on “Add API Key” in the upper right hand corner and name it “UnityGame.”
Once you’ve created your new API key, it should take you to a page showing the Space ID and Content Delivery API-access token. Copy these somewhere you can easily reference; we will need these when we start using the Contentful CSharp library.
Creating the service
To work with the Contentful Delivery API, we will create a singleton called ContentfulService. This class will be responsible for setting up the ContentfulClient and getting a specified entry.
Right click in the Project view and select Create > Folder and name it Services.
Then inside the Services folder, right click and select Create > C# Script, naming this script ContentfulService. Give ContentfulService the following code:
“`csharp
// ContentfulService.cs
using UnityEngine;
using Contentful.Core;
public class ContentfulService : MonoBehaviour
{
private static ContentfulService instance;
public static ContentfulService Instance
{
get
{
if (instance == null)
{
GameObject go = new GameObject(“ContentfulService”);
instance = go.AddComponent
DontDestroyOnLoad(go);
}
return instance;
}
}
private ContentfulClient client;
private string deliveryToken = “your-delivery-token”;
private string spaceId = “your-space-id”;
private string environment = “master”;
private void Awake()
{
client = new ContentfulClient(deliveryToken, spaceId, environment);
}
public ContentfulClient GetClient()
{
return client;
}
}
“`
Fill out the deliveryToken
, spaceId
, and environment
with the correct data.
When the game starts, the Awake()
method in ContentfulService will run, instantiating a new ContentfulClient. All subsequent requests will be made with that ContentfulClient until the player closes their game.
This service also provides a GetEntry()
method. This method is generic and will require us to specify the data we are expecting to get back from the CDA.
Since our entry has three layers (Shop Container > Shop Item > Game Item), we must use the QueryBuilder.Include()
method to specify how many layers we wish to receive.
“`csharp
// Sample code for querying the Shop Container entry
var builder = new QueryBuilder
“`
Creating the data structures around our content types
In order for us to map data from Contentful to C#, we will need to create some classes that represent our content types.
Create a new folder named EntryData, this will house all of our content type classes.
Next, we will want to create an interface that the classes, which represent the content types, will utilize. This enables us to ensure that all entries will have SystemProperties.
“`csharp
// IEntity.cs
using Contentful.Core.Models;
public interface IEntity
{
SystemProperties Sys { get; set; }
}
“`
Now that we have our interface, let’s create our game item!
One class down, two to go. Logically, the Shop Item class comes next, since it is reliant on a GameItem reference.
Last but not least, the Shop Container. Everything is pretty much the same as the last two classes, except we are now dealing with many references. Thankfully, these simply convert to Lists in C#.
Displaying your content from Contentful
We will want to first create a game object in our scene to hold our ContentfulService:
- Right click in the hierarchy and create a new empty game object.
- Attach the ContentfulService script to the game object.
Fill out deliveryToken
, spaceId
, and environment
with the correct data. Hit play and verify no console errors appear. Now we’ll create the UI.
Creating the UI: ShopCard Prefab
Step one is to create a Canvas.
Then create a Panel and set it to a width of 200 and a height of 250.
Next, add a TextMeshPro component for the title.
Then add a TextMeshPro component for the price.
Add a TextMeshPro for the description.
Add a TextMeshPro for the “On Sale” status.
Create a new empty GameObject and add a Vertical Layout Group. Make sure to check Height for the “Control Child Size” option.
Add a TextMeshPro inside of this new Vertical Layout Group for the Strength, Defense, and Speed stat.
Creating the UI: Shop Prefab
Create a Panel and add a Vertical Layout Group component. Make sure to check Width and Height for the “Control Child Size” option.
Inside the previously created Panel, nest two new Panels with Horizontal Layout Group components attached to them.
Controlling the UI: ShopCard UI
Next we will create the ShopCardUI class. This controls the data shown on the shop card. Attach this script to the ShopItem prefab and make sure to assign all the fields.
Controlling the UI: Shop
Lastly, the Shop class will be responsible for requesting the shop data from the service. Then populating the shop with ShopCards. Attach this script to the Shop prefab and fill it out.
We will need the entry id of the shop we created in Contentful to fill out the ShopId property. To get the entry id:
- Go to the content tab in Contentful.
- Click the triple dot to the right of the shop.
- Click “Copy entry ID” and then paste it into the ShopId field in Unity.
Now that we have all of our code and UI created, we can test out our creation. Make sure the ContentfulService and Shop prefab are in the scene. Hit the play button at the top and watch your shop populate!
Conclusion
To summarize what we have done:
- Created a new Contentful space to house our game’s content types.
- Made entries to represent our game’s items and shop.
- Created a service that applies our credentials and allows us to easily use the CDA throughout our game, by utilizing the ContentfulClient.
- Created classes to mirror our content types from Contentful.
- Created a shop that displays up-to-date items based off of content within Contentful, without the need for a new development build.
This article just scratches the surface of what Contentful can do to empower the game development process. Here are a few quick potentials:
- Composition of many different types of assets (3d models, textures, sound, etc.).
- A straightforward localization solution. Enable game designers and content teams to make changes to game content regardless of technical expertise.
Thanks for reading, I hope you found this guide useful! And don’t forget, you can check out the complementary repo on GitHub for reference.
Start building
Use your favorite tech stack, language, and framework of your choice.