Upgrades System
For that one user that asked!
With Inventool v2, it's possible to create your own item-related systems aside from the existing ones (inventory, crafting, enchanting, shop, and storage).
In this section, we’ll walk through how to create a custom item upgrade system. The system is built around item sockets—slots embedded within items that allow other items to be inserted to enhance their power. We'll also cover how the socket data can be used to dynamically change the display name of the item.
System Analysis
Since the purpose of this tutorial is for learning, this will be a rather simple system for the sake of time. Here are the requirements for the system:
Items that support sockets and items that can be socketed
A UI window that allows the player to edit the socketed items (max 2 sockets for simplicity)
Applying the socket data to the item (enhancing its power & updating the name)
The name will be updated based on the prefix and suffix data taken from the socketed items.
Feasibility
There are two notable features that make developing this system possible:
Custom Fields: Custom fields are data you can add to items without code, are editable at runtime, and are saved along with the item itself.
Blocks: Blocks is the core of Inventool's UI. It's a modular system that allows you to create your own UI that works with Inventool's objects. Blocks can be something small, like a text block, or large, like an inventory block, and each block is customizable and optional.
These two features will the main focus points in this tutorial.
Prerequisites
You should have some items, item types (required by items), and stats already created if you're planning on following along in this tutorial.
Developing the System
Step 1: Socket Data

This part is pretty simple; we just need to add sockets to items. We can do this through the items tab in the Object Manager by selecting an item and adding an Item Stack field under Custom Fields.
Since sockets are essentially empty slots, we don't need to set an item reference on the fields, but you can if you want to. Setting an item reference would make the item a "default" socketed item.
This step needs to be repeated for each item that should support sockets.
Step 2: Prefix/Suffix Data

Since we want the socketed data to change the name of the item, we can add custom string fields for items that can be socketed. For example, the "Electric Gem" was given a string field called "Suffix" with the value set to " of Electricity." So, when set on an item called "Sword," combining them would give us "Sword of Electricity."
This step needs to be repeated for each item that can be socketed.
Step 3: Stats

Our socketable items need to enhance the item they're applied to. So, we need to give them stats through the Stats Manager.
This step needs to be repeated for each item that can be socketed.
Step 4: Custom Window

We need to create a custom window that can display the item and sockets. This is where the Blocks system comes in.
All blocks are available through the GameObject menu (right-click in the hierarchy, navigate to Inventool > Blocks).
Here are the steps to create this window:
Add a Draggable Window Block.
Rename the title to Upgrade.
Add a Text Block and Image Block as a child of the window's container object (look for a child object named Container).
Position the text block at the top and the image at the left-hand side.
Add 2 Item Slot Blocks and position them in the right-hand side (one above the other). These slots represent the sockets.
Optional: edit the default look of the slots (a basic circle PNG was applied for this example).
For each socket, add item type restrictions from the inspector (Accepted Item Types list). It's recommended to create an item type for socketable items and set the restriction to only that type.
Step 5: Coding the System
This step is the most complex, as it requires scripting. We'll be creating a script that handles both the data and UI logic of our upgrades system.
The script needs to:
Target a specific item
Display socketed items of the target item
Update the socket data of the target item whenever socketed items are removed/added
Update the name displayed based on the socketed items
Section 1: Namespaces
Start off by adding the required namespaces we will be using.
Section 2: Inherit From Draggable Window
Most blocks generally support inheritance, and is usually recommended for customization purposes.
Create a new class and inherit from the generic DraggableWindowBlock class.
✅ Inheriting from the generic windows (instead of non-generic) makes the window singleton. This is great for us because we only need one instance of it in the scene.
❌ For example, the code below would create a window that's not singleton.
The benefit of singleton windows is ease of access and to forcefully prevent duplicates.
✅ Singleton windows can be accessed like this:
❌ This will not work for non-singleton windows.
Section 3: Reference Required Fields
Add fields that will be used to reference the required components. We need to reference the blocks we added in the previous step and an inventory block that displays the player's inventory.
You don't need to keep the same naming convention if you don't want to.
Each field can now be set from the inspector, which we can do later.
Also, add a fields to store the target item and names of the sockets as they are in data.
Section 4: On Cache
You may see errors in this step, which will be resolved later on.
For all blocks, it's recommended to override OnCache to "prepare" the object as you would in Awake or Start for general Unity components.
The first thing we're going to do inside this method is set up the slots We need the slots to work with a specific inventory, which we already have a reference to. However, the InventoryBlock is not the inventory itself—it simply binds to one. So we need to ensure the InventoryBlock is bound before setting the link on the slots.
We can do this by using Schedule, a Blocks feature built around coroutines, to wait for the inventory to be bound.
Next, we need a way to open the window and target a specific inventory item. We can do this by customization the actionMenuOptionsGetter of the inventory block.
So, the only way we can open the window is through the ActionMenuBlock and only supported items (items with at least one socket) will have the option to open it.
Finally, we need to add events to the slots that will update socketed data based on the inserted items.
Section 5: Event Handlers
In the previous section, we added events, but referenced methods that don't exist yet. We're going to create them in this section.
The method will be fairly simple—they will simply update the socket data, combine or uncombine socket item stats with or from the target item, and update the display name.
Section 6: Open Window
All windows already have an Open method, but we need one that will also set the target to a specific item.
First of all, we need to understand what Open should do. This method is called when the UI should be shown to the player, so it should populate all UI elements to accurately represent the data of the target item.
So, start off the method by setting the target item. The if statement is just for null safety checks (optional).
Silently unbind both sockets (slots) so that any previous data isn't displayed while avoiding invoking events.
Call the open method. This is the method that actually enables the window.
Bind the iconDisplay field to the target item's icon (displays the icon).
At this stage, the sockets need to reflect the current socket state of the target item. To do this, we simply retrieve the socket data and bind it to each slot—without invoking binding events, since those would trigger data updates that aren’t needed when the UI first opens.
Additionally, if the target item does not include a particular socket, that slot should be disabled so it isn’t displayed.
Finally, to allow the display name to update dynamically based on socketed items, we bind the name display block using custom logic. This logic extracts the prefix and suffix from the socketed items and combines them with the base name of the target item.
That's all! See Complete Script for the full script.
Step 6: Replace Original Draggable Window Script

Click on the Draggable Window Block we added in Step 4: Custom Window remove the Draggable Window Block component, and add the Upgrade Window component.
Also, set all its required properties through the inspector. Note: Content must be the first child object of the window.
Complete Script
Final Result
See this system in action!
Last updated