Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 62

Building a Buy Mode Catalog UI

Recommended resources

Hello! Let's dive into the next step of building your game's economy.

In the last lesson, you meticulously designed a JSON schema to serve as a blueprint for all purchasable objects. This was a crucial architectural decision that ensures consistency and makes your game highly moddable. You now have a formal contract for what an object's data should look like.

Today, we'll bring that data to life. This lesson is all about bridging the gap between your JSON data file and a functional user interface. You will build a 'buy mode' catalog UI in Unity that loads your collection of purchasable objects from a JSON file and displays them in a scrollable, grid-based catalog for the player to browse.

1. From JSON Data to C# Objects

Before Unity can display anything, it needs to understand the data. Our first task is to read the objects.json file and parse its contents into C# objects that our scripts can work with. Since this data is primarily for the UI, we'll handle this process directly within Unity, which aligns with its role as the frontend of our architecture.

1.1. Creating the Data Model in C#

You need to create C# classes that mirror the structure of your JSON objects. Unity's JsonUtility requires these classes to be marked with the [System.Serializable] attribute to work.

Based on the schema from our last lesson, you'll need two classes:

  1. A class for a single object, let's call it PurchasableObject.
  2. A "wrapper" class for the entire catalog, ObjectCatalog, which contains an array or list of PurchasableObject. This is a necessary step because Unity's JsonUtility cannot deserialize a JSON array from the root level directly.
// In a new C# script, e.g., "ObjectModels.cs"

[System.Serializable]
public class PurchasableObject
{
    public string id;
    public string name;
    public string description;
    public int cost;
    public NeedEffects need_effects;
}

[System.Serializable]
public class NeedEffects
{
    public float hunger;
    public float energy;
    public float social;
    public float fun;
}

[System.Serializable]
public class ObjectCatalog
{
    public PurchasableObject[] objects;
}

Notice how this structure directly maps to the JSON schema you created.

1.2. Loading and Deserializing the JSON File

Now, let's write the code to load the data.

  1. Create a new folder named Resources inside your Unity project's Assets folder if it doesn't already exist.
  2. Inside Resources, create a new JSON file named objects.json.
  3. Populate objects.json with a few sample items that conform to your schema. Make sure it's a root-level object containing an "objects" array, like this:
{
  "objects": [
    {
      "id": "obj_bed_simple",
      "name": "Simple Single Bed",
      "description": "A straightforward bed. No frills attached.",
      "cost": 350,
      "need_effects": {
        "energy": 75,
        "fun": -5
      }
    },
    {
      "id": "obj_chair_dining",
      "name": "Basic Dining Chair",
      "description": "A place to sit. That's about it.",
      "cost": 60,
      "need_effects": {
        "energy": 10
      }
    },
    {
      "id": "obj_fridge_basic",
      "name": "Mini Fridge",
      "description": "Keeps a small amount of food cold.",
      "cost": 600
    }
  ]
}

The following tutorial provides a clear guide on the exact steps for loading a JSON file from the Resources folder and parsing it using the wrapper class pattern we just discussed.

Simple JSON to Store Game Data in Unity

The article 'Simple JSON to Store Game Data in Unity' by Jonathan Yu provides a concise walkthrough of loading and parsing JSON, which is exactly what we need.

Read the sections 'Using JSON with your Unity Objects' and 'Reading the JSON objects'. Focus on how the C# Item and ItemArray classes are structured and how Resources.Load and JsonUtility.FromJson are used to get the data. Note that our JSON has a root key objects, so our C# code will look slightly different than the example, but the principle is identical.


2. Building the Scrollable Catalog UI

With the data loading logic in place, let's build the UI foundation in Unity. We need a window that can display a potentially large number of items, so a scrollable grid is the perfect solution.

This video gives a step-by-step demonstration of setting up a ScrollView with a GridLayoutGroup.

Grid Layout with Scroll View in Unity - Inventory System in Unity P4

The video 'Grid Layout with Scroll View in Unity' from Sunny Valley Studio is an excellent practical guide to creating the exact UI structure we need.

Watch from the beginning up to 06:32. Follow along in the Unity Editor to: Create a ScrollView inside your main UI canvas. Disable horizontal scrolling and configure the Scroll Rect component. Add a Grid Layout Group component to the Content child object of the ScrollView. Adjust the Grid Layout Group settings (Padding, Cell Size, Spacing) to define the layout of your catalog items.

After following the video, your UI hierarchy should look something like this:
Canvas -> BuyModePanel -> ScrollView -> Viewport -> Content.

The Content object is where we will dynamically add our catalog items. The GridLayoutGroup on it will handle all the positioning for us.

Unity Editor: Grid-Based UI for a Shop Catalog
This image shows a typical setup for a `Grid Layout Group` in the Unity Inspector. Your goal is to configure these properties to create a visually appealing grid for your object catalog.

3. Creating the Catalog Item Prefab

Now we need a template for each individual item in the catalog. We'll create a Prefab that we can instantiate for every object loaded from our JSON file.

  1. Inside your Content object, create a new UI Panel. This will be your item template.
  2. Resize this panel to match the Cell Size you set in the Grid Layout Group.
  3. Add child UI elements to this panel:
    • An Image to eventually show a picture of the object.
    • A Text or TextMeshPro - Text element for the object's name.
    • Another Text element for the object's cost.
    • A Button for purchasing the item (we'll make it functional in the next lesson).
  4. Style these elements as you see fit.
  5. Once you're happy with the layout, drag this panel from the Hierarchy into your Project window to create a Prefab. You can now delete the instance from your Content object.
Unity Shop UI Panel Example
This image is a great reference for what a finished catalog can look like, with each item showing an image, a price, and a 'BUY' button.

4. Dynamically Populating the Catalog

This is where everything comes together. We'll write a script to load the JSON, loop through the items, and create a UI element for each one using our new prefab.

Create a new C# script called CatalogManager.cs and attach it to your main BuyModePanel or another suitable manager object in your scene.

The following resource provides a fantastic template for a script that dynamically populates a scrollable menu. We will adapt its logic for our catalog.

Scrollable Menu in Unity with button or key controller

The article 'Scrollable Menu in Unity' from Pav Creations has an optional section on dynamically populating a menu, which is precisely what we need to do.

Read section 4, 'The dynamic population of the scrollable menu in Unity'. Pay close attention to the logic inside the OnEnable() method. We will use a similar pattern in our Start() method: iterate through the loaded data, instantiate a prefab, and set the values on its components.

Here is a complete CatalogManager.cs script that combines the JSON loading from Part 1 with the dynamic population logic.

using UnityEngine;
using UnityEngine.UI;
using TMPro; // Add this if you are using TextMeshPro

public class CatalogManager : MonoBehaviour
{
    // Reference to the content panel of the ScrollView
    public Transform contentPanel; 
    // Reference to the item prefab you created
    public GameObject catalogItemPrefab; 

    void Start()
    {
        LoadAndDisplayObjects();
    }

    void LoadAndDisplayObjects()
    {
        // Load the JSON file from the Resources folder
        TextAsset jsonFile = Resources.Load<TextAsset>("objects");
        if (jsonFile == null)
        {
            Debug.LogError("Cannot find objects.json in Resources folder!");
            return;
        }

        // Deserialize the JSON into our C# objects
        ObjectCatalog catalog = JsonUtility.FromJson<ObjectCatalog>(jsonFile.text);

        // Loop through each object in the catalog
        foreach (PurchasableObject obj in catalog.objects)
        {
            // Instantiate a new catalog item from the prefab
            GameObject itemGO = Instantiate(catalogItemPrefab, contentPanel);

            // Find the UI elements within the instantiated prefab
            // NOTE: You may need to adjust these paths based on your prefab's hierarchy
            TextMeshProUGUI nameText = itemGO.transform.Find("NameText").GetComponent<TextMeshProUGUI>();
            TextMeshProUGUI priceText = itemGO.transform.Find("PriceText").GetComponent<TextMeshProUGUI>();
            // Example: Image iconImage = itemGO.transform.Find("Icon").GetComponent<Image>();

            // Populate the UI elements with data from the object
            if (nameText != null) nameText.text = obj.name;
            if (priceText != null) priceText.text = $"${obj.cost}";
            
            // We'll wire up the button's onClick listener in the next lesson
        }
    }
}

To finish:

  1. Attach this script to an object in your scene.
  2. Drag your Content panel and your catalogItemPrefab into the corresponding public fields in the Inspector.
  3. Ensure the Find paths (e.g., "NameText") match the names of the text objects in your prefab.
  4. Press Play. Your catalog should magically populate with the items from your JSON file!

Conclusion

Congratulations! You've successfully built a data-driven UI system. You created a ScrollView in Unity, loaded object data from a JSON file, and dynamically generated a UI for each item at runtime. This is a robust and scalable foundation for your game's 'buy mode'.

Key Takeaways:

  • You mapped a JSON structure to [System.Serializable] C# classes to allow for parsing with JsonUtility.
  • You learned to handle JsonUtility's limitation with root-level arrays by using a wrapper class.
  • You constructed a scrollable grid UI using a ScrollView and a GridLayoutGroup.
  • You created a reusable Prefab for a single catalog item.
  • You wrote a manager script that loads data and populates the UI by instantiating prefabs at runtime.

Preview of the Next Lesson:
Our catalog looks great, but the "Buy" buttons don't do anything yet. In the next lesson, we will implement the purchase transaction. You'll learn how to handle button clicks, send a command to the Rust backend to check the character's funds, deduct the cost, and finally add the object to the world.