Sleek Inventory

Overview

Sleek Inventory allows creating flexible and powerful inventory systems in Unity. Get it from the Unity Asset Store. The system supports multiple pages with tabs, dragging and dropping of items onto scene objects, tooltips on items, easy screen alignment, and more. All code is written in C# and the system is provided as an encapsulated and independent plugin within the Unity project. Scripting experience is required as the content of an inventory needs to be added by help of code.

Live Demos

Asset Store Link

Support

Simple Inventory Setup (1 Page, 1 Item)

The following text describes the code that is necessary to create an inventory with a single page and 1 item. There’s also a unity example scene that completely implements this setup (SleekInventory1_SinglePageInventory.unity).

First you need to add the SleekInventory component to a gameobject in the scene. In addition you need another controller script that takes care of adding the content. In the example scene there’s the test_inventory gameobject that contains the inventory and controller component. There’s an additional script on this gameobject that simplifies the use of textures with the inventory. This component is optional.

The controller should be a class that implements the SleekInventorySystem.IInventoryPageGenerator interface. This interface defines a method that returns the generated inventory pages. The generation is invoked by calling the CreatePages() method of the SleekInventory component. The method takes as parameter a class that implements the PageGenerator interface.

testInventory.CreatePages(this);

Setting the content of the inventory takes place in the GeneratePages() method.

public List<AbstractInventoryPage> GeneratePages() {

  //First: Create a list that will contain the inventory pages.
  List<AbstractInventoryPage> pages = new List<AbstractInventoryPage>();

  //Define the amount of inventory slots per page.
  int inventorySizeX = 5;
  int inventorySizeY = 4;

  //Add 1 page.
  pages.Add(new ItemGridPage(inventorySizeX, inventorySizeY));

  //Texture loading helper.
  SleekInventoryTextureContainer textureContainer =
    this.gameObject.GetComponent<SleekInventoryTextureContainer>();

  //Create 1 simple image item.
  ImageItem item1 = new ImageItem(textureContainer.GetTextureByFilename("test_icon_helmet"));

  //Assign the item to specific pages of the inventory and to a specific slot.
  //The index into the pages array defines the page of the item.
  //The first 2 parameters of the SetSlotItem() method define
  //the position in the inventory grid of the page.
  (pages[0] as ItemGridPage).SetSlotItem(0, 0, item1);

  //Pages are created now so let's return them.
  return (pages);
}

Inspector Settings

In order to fine tune the appearance of the inventory there are several properties that can be tweaked in the inspector window of the Sleek Inventory component.


  • GUI Skin: The skin that defines the look of the inventory. The skin contains a number of custom styles for the background, inventory slots and tab button images.
  • Inventory Alignment: The placement of the inventory on the screen.
  • Inventory Position Offset: Pixel offset that allows to fine tune the position of the inventory on the screen.
  • Inventory Size: The size of the inventory in pixel dimensions.
  • Tab Button Height: The height of the tab button that is shown for multi page inventories.
  • Tab Button Max Width: The width of the tab button for multi page inventories.
  • Tab Button Indent: The tab buttons can be indented from the left and right border of the inventory by help of this property.
  • Page Indent Left/Right/Top/Bottom: The content of an inventory can be indented from the outer border by help of these pixel values.
  • Show: A bool toggle that allows to show or hide the entire inventory.
  • Enable Item Dragging: Toggle to define whether or not a user is allowed to drag around items to different slots.
  • Enable Item Swapping: If this toggle is set to true and the user drags an item onto another item, the 2 items swap their position in the inventory.

GUI Skin

The GUI Skin set in the inspector property shown above defines what the inventory looks like. There are 5 important textures that need to be set.

  • inventory_slot_background: The background image for a single slot that can contain an item.
  • inventory_slot_highlighting: An image that is displayed when the user drags an item over an item slot.
  • inventory_tab_button: Image for the tab button that allows to switch between pages of an inventory.
  • inventory_background: The background texture for the entire inventory.
  • inventory_tooltip_background: Background texture for the tooltips of items.

Item Types

Currently there are 2 types of items built into the system. Using subclassing however it is easy to add new items with enhanced behaviour.

  • ImageItem: Displays a simple image. Can be constructed with a Unity Texture object and an optional tooltip text.
  • ImageAndNumberItem: Displays an image and a number in the bottom left corner. Can be constructed with a Unity Texture object, a number and an optional tooltip text.

The SleekInventory2_MultiPageInventory.unity sample scene that is included in the package shows the construction of these items.

//Regular image item.
ImageItem item1 =
  new ImageItem(textureContainer.GetTextureByFilename("test_icon_helmet"));
//Item with tooltip.
ImageItem item2 =
  new ImageItem(textureContainer.GetTextureByFilename("test_icon_sword"),
  "icon with tooltip");
//Items that displays an image and a number.
ImageItem item3 =
  new ImageAndNumberItem(textureContainer.GetTextureByFilename("test_icon_potion"), 100);

Multiple Pages with Tabs

How to create multiple pages can be seen in the TestInventoryController_MultiPageInventory class that comes with the package. The relevant lines of code are shown in the following:

//Add 3 pages.
pages.Add(new ItemGridPage(inventorySizeX, inventorySizeY));
pages.Add(new ItemGridPage(inventorySizeX, inventorySizeY));
pages.Add(new ItemGridPage(inventorySizeX, inventorySizeY));

You simply create and add as many pages as you want the inventory to contain. Tabs are added automatically.

Once the pages are created, you can assign items to all existing pages using the following code:

//The index into the pages array defines the page of the item.
//The first  2 parameters of the SetSlotItem() method define the position in the  inventory grid of the page.
(pages[0] as ItemGridPage).SetSlotItem(0, 0, item1); //Add item1 to page 0.
(pages[1] as ItemGridPage).SetSlotItem(3, 1, item4); //Add item4 to page 1.
(pages[2] as ItemGridPage).SetSlotItem(4, 3, item6); //Add item6 to page 2.

Interacting with Scene Objects

The code for scene interaction as shown in Example3 can be found in the TestInventoryController_DragItemOnGameObject class that is shipped with the package. Again here are the relevant pieces of code that are necessary for the scene interaction:

ColliderDragTarget dragTarget1 = new ColliderDragTarget(GameObject.Find("/Cube1").collider,
                                                        InventoryItemDroppedOnTarget1);
testInventory.AddCustomDragTarget(dragTarget1);

First a custom drag target needs to be created and assigned to the inventory. Scene interaction only works with objects that have a Collider component attached. This collider needs to be given as first parameter of the construction of the drag target. The second parameter is a callback method that is invoked every time a user drops an item onto the collider. The callback method must have the following signature:

bool CallbackMethodName(AbstractDraggableItem draggableItem)

In the example controller the full callback method looks as follows:

private bool InventoryItemDroppedOnTarget1(AbstractDraggableItem draggableItem) {
  Transform cubeTransform = GameObject.Find("/Cube1").transform;
  cubeTransform.renderer.material.mainTexture = (draggableItem as ImageItem).Icon;
  return (true);
}

The input parameter is exactly the item that has been dropped on the collider. Attention must be directed to the return value of the callback. When true is returned, the item is removed from the inventory as it has been successfully dropped on the target. When false is returned, the drop is aborted and the item is put back into the inventory to where it was before.

Texture Container Helper Script

All examples in the package make use of a little helper script class called SleekInventoryTextureContainer. The use of this class is completely optional. All it does is allow to access images from the project in a simple way. Images can be added to the ‘itemTextures’ array from the inspector, and then be retrieved through the script by help of the GetTextureByFilename() method.

Help with Save&Load

Update 1.1 now contains a few helper classes and methods that aid in saving and loading the state of a grid inventory. There’s a separate test-scene that serves as showcase: SleekInventory5_SaveAndLoad.unity. Saving the inventory state to a string using these methods works like this:

string inventoryStateString = GridInventory.SaveGridItemStateToString(testInventory);

The string can be stored in the player prefs easily. Loading the inventory from the string involves a little more work. The code for loading should be inserted into the GeneratePages() method that handles the generation of inventories. Given the inventory string above you may use the following call to load the inventory from it:

public List GeneratePages() {
  return GridInventory.CreateGridInventoryFromStateString(inventoryStateString, CreateInventoryItem);
}

For this to work the callback method (in this example named as CreateInventoryItem) needs to be given as parameter. This method helps creating the items and loading custom data into them. In the sample scene this helper method looks as follows:

private AbstractDraggableInventoryItem CreateInventoryItem(GridInventoryItemDescription itemDescription) {

  //Texture loading helper.
  SleekInventoryTextureContainer textureContainer = this.gameObject.GetComponent();

  JsonFx.Json.JsonReader itemReader = new JsonFx.Json.JsonReader(itemDescription.ItemData);
  ImageItem item = null;
  switch (itemDescription.ItemType) {
    case "SleekInventorySystem.ImageItem":
      //Create the item by deserializing the item data.
      item = itemReader.Deserialize();
      //Load custom content that cannot be loaded by plain deserialization.
      item.Icon = textureContainer.GetTextureByFilename(itemDescription.IconName);
      break;
    case "SleekInventorySystem.ImageAndNumberItem":
      //Create the item by deserializing the item data.
      item = itemReader.Deserialize();
      //Load custom content that cannot be loaded by plain deserialization.
      item.Icon = textureContainer.GetTextureByFilename(itemDescription.IconName);
      break;
    //Add more cases here when using custom items.
    default:
      Debug.LogError("SleekInventory: Failed to deserialize item of type '" + itemDescription.ItemType + "'");
      break;
  }
  return (item);
}

Note that itemDescription.ItemData holds the serialized information of a stored item. Items may be directly created from this description in the way shown above. Not all data may be loaded this way however. Complex data, like textures may be loaded manually after the item was created from deserialization. This is also shown above.

Code Reference (v1.1)

2 thoughts on “Sleek Inventory

Leave a Reply

Your email address will not be published. Required fields are marked *