CywerStudioCywerStudio
View products
v1.0 Unity 2022.3 LTS+ Mirror Server-Authoritative

NetInventory Pro

Multiplayer Inventory System for Unity + Mirror — Version 1.0. A fully network-authoritative inventory where every item transaction runs through the server.

40-Slot Inventory Server-Authoritative Drag & Drop UI Stack Management JSON Save / Load Item Tooltips World Item Drop Auto Proximity Pickup Hotbar + Grid

01 Overview & Features

NetInventory Pro is a fully network-authoritative inventory system built for Unity with the Mirror networking library. Every item transaction — adding, removing, swapping, splitting, merging, dropping, and picking up — runs through the server, making it safe for multiplayer games where client authority would be a cheat risk.

Feature Highlights

02 Requirements

DependencyVersionNotes
Unity2022.3 LTS or newer
MirrorLatest stable releaseAvailable on the Asset Store or GitHub
TextMeshProAny versionIncluded with Unity
Render PipelineBuilt-In or URPHDRP not tested
Scripting BackendMono or IL2CPP

This asset requires Mirror Networking. It will not compile or function without Mirror installed. Install Mirror before importing this package.

03 Installation

Step 1 — Install Mirror

Open the Unity Asset Store window and import Mirror into your project. Alternatively, install it via the Package Manager using the Mirror GitHub URL.

Step 2 — Import NetInventory Pro

In the Unity Editor, go to Assets → Import Package → Custom Package and select the NetInventoryPro.unitypackage file. Import all assets.

Step 3 — Verify TextMeshPro

If prompted, click Import TMP Essentials in the TextMeshPro setup window. The UI prefabs require TMP to display item names and stack counts.

Step 4 — Open the Demo Scene

Navigate to Assets/Scenes/ and open DEMO.unity. Press Play to verify everything is working before integrating into your own project.

04 Project Structure

After import, the following folders will be present in your project:

PathContents
Script/Inventory/All inventory C# scripts
Script/Player/PlayerMovement script
Prefabs/SlotPrefab, DroppedItem, InventoryUI prefabs
Resources/Items/Item ScriptableObject assets (Wood, Stone, etc.)
Resources/Player.prefabPlayer prefab with all components pre-configured
Scenes/DEMO.unityDemo scene — open this first to verify setup

Item assets must remain inside a Resources/ folder so they can be loaded at runtime with Resources.Load(). Do not move them outside Resources/.

05 Quick Start

The fastest way to get started is to use the pre-configured Player prefab:

Step 1 — Add a Network Manager

Drag a Mirror NetworkManager into your scene if you do not already have one.

Step 2 — Register the Player prefab

Open Resources/Player.prefab and assign it as the Player Prefab in your NetworkManager's Registered Spawnable Prefabs list, and in the Player Prefab field.

Step 3 — Add the InventoryUI to your scene

Drag the Prefabs/InventoryUI prefab into your scene. Assign the references (gridParent, hotbarParent, tooltipPanel, etc.) if not already set.

Step 4 — Register the DroppedItem prefab

Add Prefabs/DroppedItem to the NetworkManager's Registered Spawnable Prefabs list.

Step 5 — Press Play

Start a host from the NetworkManager HUD. Your player will spawn with a fully functional inventory.

06 Creating Items

Items are defined as ScriptableObject assets. Each asset represents one item type (e.g. Wood, Iron Sword, Health Potion). You do not need to write any code to add new items.

Creating a New Item Asset

ItemData Fields

FieldTypeDescription
itemNamestringDisplay name shown in tooltips and UI
iconSpriteIcon displayed in inventory slots and when held
descriptionstringShort description shown in the tooltip
stackableboolWhether multiple units share a slot
maxStackintMaximum units per stack (default: 64)
itemTypeItemTypeResource / Tool / Weapon / Consumable / Seed / Food
toolTypeToolTypeOnly relevant when itemType is Tool
damageMultiplierintHits removed per swing (for tools/weapons)

Supported Item Subfolders

The system searches the following paths inside Resources/ when loading items at runtime:

The item id used in code is the asset filename, not the itemName field. For example, an asset named 'IronSword' is referenced as AddItem("IronSword", 1).

07 Integrating into Your Player

If you are using your own player prefab instead of the provided one, add the following components to your player GameObject:

ComponentPurpose
InventoryCore inventory data and network sync
InventoryLinkerLinks the Inventory to the InventoryUI when the local player spawns
InventorySaveManagerHandles save and load of inventory state on the server
ItemDropperHandles dropping items and proximity pickup
HeldItemDisplaySyncs and displays the currently held item sprite
PlayerMovementTop-down movement with UI-aware input blocking

InventoryLinker

InventoryLinker connects the local player's Inventory component to the singleton InventoryUI when the player object starts on the client. Without this component the UI will not display the correct inventory.

Blocking Movement from External UI

If you have UI panels outside of the inventory system, you can block player movement while they are open by assigning a delegate to PlayerMovement.IsUIOpen:

// In your UI script or game manager:
PlayerMovement.IsUIOpen = () => MyCustomUI.Instance.IsOpen;

08 Inventory System Reference

The Inventory component is the central authority for all item data. It runs on the player GameObject and all public methods that modify state are server-only. Clients interact with it exclusively through Commands.

Constants

ConstantValueDescription
TOTAL_SLOTS40Total number of inventory slots
HOTBAR_SLOTS8Slots 0–7, displayed in the hotbar
GRID_SLOTS32Slots 8–39, displayed in the grid panel

Server Methods

MethodDescription
AddItem(string itemId, int amount = 1)Adds items to the inventory, filling existing stacks first. Returns true if at least one unit was added.
RemoveItem(string itemId, int amount = 1)Removes items by id, searching from the last slot backwards. Returns true if at least one was removed.
RemoveSlot(int slotIndex, int amount = 1)Removes a specific amount from a single slot by index. Returns true on success.

Commands (client → server)

CommandDescription
CmdAddItem(string itemId, int amount)Client-callable wrapper for AddItem.
CmdRemoveSlot(int slotIndex, int amount)Client-callable wrapper for RemoveSlot.
CmdSwapSlots(int fromIndex, int toIndex)Swaps two slots. Merges stacks if both hold the same stackable item.
CmdTransferOne(int fromIndex, int toIndex)Moves exactly one unit between slots (right-click split).
CmdDistributeAcrossSlots(...)Spreads a stack evenly across multiple target slots (right-drag).
CmdMergeStacks(int fromIndex)Gathers all stacks of the same item into the source slot (double right-click).
CmdSelectHotbar(int index)Changes the active hotbar slot (0–7).

Example: Adding an Item from External Code

// From a server-side script (e.g. a chest or resource node):
Inventory inv = player.GetComponent<Inventory>();
inv.AddItem("Wood", 5);

// From a client-side script:
Inventory inv = GetComponent<Inventory>();
inv.CmdAddItem("Stone", 3);

09 UI System Reference

InventoryUI

InventoryUI is a singleton MonoBehaviour that manages all UI elements. It instantiates slot prefabs, handles input for opening/closing, scroll wheel hotbar cycling, number key selection, tooltip display, and slot swapping.

FieldTypePurpose
inventoryPanelGameObjectRoot panel shown when the inventory is open
gridParentTransformParent for the 32 grid slot objects
hotbarParentTransformParent for the 8 hotbar slot objects
slotPrefabGameObjectPrefab instantiated for each slot
tooltipPanelGameObjectRoot of the tooltip popup
tooltipNameTMP_TextItem name label
tooltipTypeTMP_TextItem type label (colour-coded)
tooltipDescriptionTMP_TextItem description label
tooltipStackTMP_TextMax stack size label

SlotUI — Gesture Summary

GestureAction
Left-drag to another slotSwap the two slots (merges stacks if same item)
Left-drag outside panelDrop the entire stack into the world
Right-drag across slotsDistribute the stack evenly across all visited slots
Right-click (single)Starts timer for double-click detection
Right-click (double)Merge all stacks of the same item into this slot
Right-click outside panelDrop one unit into the world
Right-click during left-dragTransfer one unit from the drag source to this slot
Hover (grid slots only)Show tooltip

10 Save & Load System

InventorySaveManager saves and loads each player's inventory as a JSON file on the server. Save files are stored in Application.persistentDataPath by default, with one file per player.

File Path

{saveFolderPath}/inventory_{playerId}.json

Default Behaviour

Custom Configuration

To provide a custom save folder or player id (e.g. SteamID), call Configure() before OnStartServer runs:

InventorySaveManager saveManager = player.GetComponent<InventorySaveManager>();
saveManager.Configure("/path/to/saves", steamId.ToString());

Changing Starter Items

Edit the GiveStarterItems() method inside InventorySaveManager.cs:

void GiveStarterItems()
{
    inventory.AddItem("Wood", 10);
    inventory.AddItem("Stone", 10);
    // Add more items here
}

11 Input Reference

Key / InputAction
EOpen / close inventory panel
QDrop one unit of the selected hotbar item
Ctrl + QDrop the entire stack of the selected hotbar item
1 – 8Select hotbar slot directly
Scroll WheelCycle through hotbar slots
WASD / ArrowsMove the player (blocked when inventory is open)

12 Extending the System

Adding a New Item Type

Open ItemData.cs and add a new value to the ItemType enum:

public enum ItemType
{
    Resource, Tool, Weapon, Consumable, Seed, Food,
    Quest // your new type
}

Then add a matching colour entry in InventoryUI.GetTypeColor() and SlotUI.GetCategoryColor().

Adding a New Tool Type

Add a new value to the ToolType enum in ItemData.cs:

public enum ToolType
{
    None, Axe, Pickaxe, Hoe, WateringCan, Sword,
    Shovel // your new tool
}

Changing the Inventory Size

Edit the constants at the top of Inventory.cs:

public const int TOTAL_SLOTS = 40; // hotbar + grid
public const int HOTBAR_SLOTS = 8;
public const int GRID_SLOTS = 32;

If you change these values, also update the UI layout (grid columns/rows) to match.

Spawning Items from External Systems

Any server-side script can drop items into the world using ItemDropper:

// e.g. a tree falls and drops logs:
ItemDropper dropper = player.GetComponent<ItemDropper>();
dropper.SpawnDroppedItem("Wood", 3, treePosition);

13 Troubleshooting

Compile errors after import

Mirror is not installed. Install Mirror first, then re-import the package.

Inventory slots are all empty after spawning

Make sure InventoryLinker is on the player prefab and that InventoryUI exists in the scene. Check that the player prefab is registered in the NetworkManager.

Item icons are not showing

Verify that each ItemData asset has a Sprite assigned to the Icon field. Also confirm the asset is inside a Resources/ subfolder.

"Item not found" warning in the console

The item id passed to AddItem or LoadItem does not match any asset filename. Item ids are case-sensitive and must match the asset filename exactly (e.g. "Wood" not "wood").

Inventory does not save between sessions

SaveInventory() must be called explicitly (e.g. on player disconnect). It is not called automatically on exit. Hook it to your disconnect event.

Dropped items are not visible to other players

Ensure the DroppedItem prefab is added to the NetworkManager's Registered Spawnable Prefabs list.

Player can still move while inventory is open

Check that InventoryUI.Instance is not null and that the IsOpen property returns true when the panel is visible.

Right-drag distribute does not work

Right-drag requires the source slot to have more than one unit. The drag threshold is 8 pixels — move the mouse further from the starting point.

NetInventory Pro — Version 1.0 · CywerStudio · Thank you for using this asset. If you have questions or feedback, please leave a review on the Asset Store.