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 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. 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. 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)