Coding a Simple Inventory System With UI Drag and Drop in Unity (2024)

Many games allow players to collect and carry around a large number of items (ex. RTS/MOBA/RPG games, Action Role-playing games, etc.), that's where the Inventory comes into play.

Inventory is a table of elements that provides quick access to player items and a simple way to organize them.

Coding a Simple Inventory System With UI Drag and Drop in Unity (1)

In this post, we will be learning how to program a simple Inventory System with Item Pick up and UI Drag & Drop in Unity.

Coding a Simple Inventory System With UI Drag and Drop in Unity (2)

Step 1: Create the Scripts

This tutorial requires 3 scripts:

SC_CharacterController.cs

//You are free to use this script in Free or Commercial projects//sharpcoderblog.com @2019using UnityEngine;[RequireComponent(typeof(CharacterController))]public class SC_CharacterController : MonoBehaviour{ public float speed = 7.5f; public float jumpSpeed = 8.0f; public float gravity = 20.0f; public Camera playerCamera; public float lookSpeed = 2.0f; public float lookXLimit = 60.0f; CharacterController characterController; Vector3 moveDirection = Vector3.zero; Vector2 rotation = Vector2.zero; [HideInInspector] public bool canMove = true; void Start() { characterController = GetComponent<CharacterController>(); rotation.y = transform.eulerAngles.y; } void Update() { if (characterController.isGrounded) { // We are grounded, so recalculate move direction based on axes Vector3 forward = transform.TransformDirection(Vector3.forward); Vector3 right = transform.TransformDirection(Vector3.right); float curSpeedX = speed * Input.GetAxis("Vertical"); float curSpeedY = speed * Input.GetAxis("Horizontal"); moveDirection = (forward * curSpeedX) + (right * curSpeedY); if (Input.GetButton("Jump")) { moveDirection.y = jumpSpeed; } } // Apply gravity. Gravity is multiplied by deltaTime twice (once here, and once below // when the moveDirection is multiplied by deltaTime). This is because gravity should be applied // as an acceleration (ms^-2) moveDirection.y -= gravity * Time.deltaTime; // Move the controller characterController.Move(moveDirection * Time.deltaTime); // Player and Camera rotation if (canMove) { rotation.y += Input.GetAxis("Mouse X") * lookSpeed; rotation.x += -Input.GetAxis("Mouse Y") * lookSpeed; rotation.x = Mathf.Clamp(rotation.x, -lookXLimit, lookXLimit); playerCamera.transform.localRotation = Quaternion.Euler(rotation.x, 0, 0); transform.eulerAngles = new Vector2(0, rotation.y); } }}

SC_PickItem.cs

//You are free to use this script in Free or Commercial projects//sharpcoderblog.com @2019using UnityEngine;public class SC_PickItem : MonoBehaviour{ public string itemName = "Some Item"; //Each item must have an unique name public Texture itemPreview; void Start() { //Change item tag to Respawn to detect when we look at it gameObject.tag = "Respawn"; } public void PickItem() { Destroy(gameObject); }}

SC_InventorySystem.cs

//You are free to use this script in Free or Commercial projects//sharpcoderblog.com @2019using UnityEngine;public class SC_InventorySystem : MonoBehaviour{ public Texture crosshairTexture; public SC_CharacterController playerController; public SC_PickItem[] availableItems; //List with Prefabs of all the available items //Available items slots int[] itemSlots = new int[12]; bool showInventory = false; float windowAnimation = 1; float animationTimer = 0; //UI Drag & Drop int hoveringOverIndex = -1; int itemIndexToDrag = -1; Vector2 dragOffset = Vector2.zero; //Item Pick up SC_PickItem detectedItem; int detectedItemIndex; // Start is called before the first frame update void Start() { Cursor.visible = false; Cursor.lockState = CursorLockMode.Locked; //Initialize Item Slots for (int i = 0; i < itemSlots.Length; i++) { itemSlots[i] = -1; } } // Update is called once per frame void Update() { //Show/Hide inventory if (Input.GetKeyDown(KeyCode.Tab)) { showInventory = !showInventory; animationTimer = 0; if (showInventory) { Cursor.visible = true; Cursor.lockState = CursorLockMode.None; } else { Cursor.visible = false; Cursor.lockState = CursorLockMode.Locked; } } if (animationTimer < 1) { animationTimer += Time.deltaTime; } if (showInventory) { windowAnimation = Mathf.Lerp(windowAnimation, 0, animationTimer); playerController.canMove = false; } else { windowAnimation = Mathf.Lerp(windowAnimation, 1f, animationTimer); playerController.canMove = true; } //Begin item drag if (Input.GetMouseButtonDown(0) && hoveringOverIndex > -1 && itemSlots[hoveringOverIndex] > -1) { itemIndexToDrag = hoveringOverIndex; } //Release dragged item if (Input.GetMouseButtonUp(0) && itemIndexToDrag > -1) { if (hoveringOverIndex < 0) { //Drop the item outside Instantiate(availableItems[itemSlots[itemIndexToDrag]], playerController.playerCamera.transform.position + (playerController.playerCamera.transform.forward), Quaternion.identity); itemSlots[itemIndexToDrag] = -1; } else { //Switch items between the selected slot and the one we are hovering on int itemIndexTmp = itemSlots[itemIndexToDrag]; itemSlots[itemIndexToDrag] = itemSlots[hoveringOverIndex]; itemSlots[hoveringOverIndex] = itemIndexTmp; } itemIndexToDrag = -1; } //Item pick up if (detectedItem && detectedItemIndex > -1) { if (Input.GetKeyDown(KeyCode.F)) { //Add the item to inventory int slotToAddTo = -1; for (int i = 0; i < itemSlots.Length; i++) { if (itemSlots[i] == -1) { slotToAddTo = i; break; } } if (slotToAddTo > -1) { itemSlots[slotToAddTo] = detectedItemIndex; detectedItem.PickItem(); } } } } void FixedUpdate() { //Detect if the Player is looking at any item RaycastHit hit; Ray ray = playerController.playerCamera.ViewportPointToRay(new Vector3(0.5F, 0.5F, 0)); if (Physics.Raycast(ray, out hit, 2.5f)) { Transform objectHit = hit.transform; if (objectHit.CompareTag("Respawn")) { if ((detectedItem == null || detectedItem.transform != objectHit) && objectHit.GetComponent<SC_PickItem>() != null) { SC_PickItem itemTmp = objectHit.GetComponent<SC_PickItem>(); //Check if item is in availableItemsList for (int i = 0; i < availableItems.Length; i++) { if (availableItems[i].itemName == itemTmp.itemName) { detectedItem = itemTmp; detectedItemIndex = i; } } } } else { detectedItem = null; } } else { detectedItem = null; } } void OnGUI() { //Inventory UI GUI.Label(new Rect(5, 5, 200, 25), "Press 'Tab' to open Inventory"); //Inventory window if (windowAnimation < 1) { GUILayout.BeginArea(new Rect(10 - (430 * windowAnimation), Screen.height / 2 - 200, 302, 430), GUI.skin.GetStyle("box")); GUILayout.Label("Inventory", GUILayout.Height(25)); GUILayout.BeginVertical(); for (int i = 0; i < itemSlots.Length; i += 3) { GUILayout.BeginHorizontal(); //Display 3 items in a row for (int a = 0; a < 3; a++) { if (i + a < itemSlots.Length) { if (itemIndexToDrag == i + a || (itemIndexToDrag > -1 && hoveringOverIndex == i + a)) { GUI.enabled = false; } if (itemSlots[i + a] > -1) { if (availableItems[itemSlots[i + a]].itemPreview) { GUILayout.Box(availableItems[itemSlots[i + a]].itemPreview, GUILayout.Width(95), GUILayout.Height(95)); } else { GUILayout.Box(availableItems[itemSlots[i + a]].itemName, GUILayout.Width(95), GUILayout.Height(95)); } } else { //Empty slot GUILayout.Box("", GUILayout.Width(95), GUILayout.Height(95)); } //Detect if the mouse cursor is hovering over item Rect lastRect = GUILayoutUtility.GetLastRect(); Vector2 eventMousePositon = Event.current.mousePosition; if (Event.current.type == EventType.Repaint && lastRect.Contains(eventMousePositon)) { hoveringOverIndex = i + a; if (itemIndexToDrag < 0) { dragOffset = new Vector2(lastRect.x - eventMousePositon.x, lastRect.y - eventMousePositon.y); } } GUI.enabled = true; } } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); if (Event.current.type == EventType.Repaint && !GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition)) { hoveringOverIndex = -1; } GUILayout.EndArea(); } //Item dragging if (itemIndexToDrag > -1) { if (availableItems[itemSlots[itemIndexToDrag]].itemPreview) { GUI.Box(new Rect(Input.mousePosition.x + dragOffset.x, Screen.height - Input.mousePosition.y + dragOffset.y, 95, 95), availableItems[itemSlots[itemIndexToDrag]].itemPreview); } else { GUI.Box(new Rect(Input.mousePosition.x + dragOffset.x, Screen.height - Input.mousePosition.y + dragOffset.y, 95, 95), availableItems[itemSlots[itemIndexToDrag]].itemName); } } //Display item name when hovering over it if (hoveringOverIndex > -1 && itemSlots[hoveringOverIndex] > -1 && itemIndexToDrag < 0) { GUI.Box(new Rect(Input.mousePosition.x, Screen.height - Input.mousePosition.y - 30, 100, 25), availableItems[itemSlots[hoveringOverIndex]].itemName); } if (!showInventory) { //Player crosshair GUI.color = detectedItem ? Color.green : Color.white; GUI.DrawTexture(new Rect(Screen.width / 2 - 4, Screen.height / 2 - 4, 8, 8), crosshairTexture); GUI.color = Color.white; //Pick up message if (detectedItem) { GUI.color = new Color(0, 0, 0, 0.84f); GUI.Label(new Rect(Screen.width / 2 - 75 + 1, Screen.height / 2 - 50 + 1, 150, 20), "Press 'F' to pick '" + detectedItem.itemName + "'"); GUI.color = Color.green; GUI.Label(new Rect(Screen.width / 2 - 75, Screen.height / 2 - 50, 150, 20), "Press 'F' to pick '" + detectedItem.itemName + "'"); } } }}

Coding a Simple Inventory System With UI Drag and Drop in Unity (3)

Step 2: Set up the Player and Inventory System

Let's begin by setting up our Player:

  • Create a new GameObject and call it "Player"
  • Create a new Capsule (GameObject -> 3D Object -> Capsule) remove the Capsule Collider component then move the Capsule inside the "Player" Object and lastly change its position to (0, 1, 0)
  • Move the Main Camera inside the "Player" Object and change its position to (0, 1.64, 0)

Coding a Simple Inventory System With UI Drag and Drop in Unity (4)

  • Attach SC_CharacterController script to "Player" Object (it will automatically add another component called Character Controller, change its center value to (0, 1, 0))
  • Assign the Main Camera to a "Player Camera" variable at SC_CharacterController

Coding a Simple Inventory System With UI Drag and Drop in Unity (5)

Now let's setup Pick Up items - these will be Prefabs of the items that can be picked in the game.

For this tutorial, I will be using simple shapes (Cube, Cylinder, and Sphere) but you can add different models, possibly some particles, etc.

  • Create a new GameObject and call it "SimpleItem"
  • Create a new Cube (GameObject -> 3D Object -> Cube), scale it down to (0.4, 0.4, 0.4) then move it inside "SimpleItem" GameObject
  • Select "SimpleItem" and add a Rigidbody component and a SC_PickItem script

You will notice there are 2 variables in SC_PickItem:

Item Name - this should be a unique name.
Item Preview - a Texture that will be displayed in the Inventory UI, preferably you should assign the image that represents the item.

In my case the Item Name is "Cube" and Item Preview is a white square:

Coding a Simple Inventory System With UI Drag and Drop in Unity (6)

Coding a Simple Inventory System With UI Drag and Drop in Unity (7)

Repeat the same steps for the other 2 items.

For Cylinder item:

  • Duplicate a "SimpleItem" Object and name it "SimpleItem 2"
  • Remove child Cube and create a new Cylinder (GameObject -> 3D Object -> Cylinder). Move it inside "SimpleItem 2" and Scale it to (0.4, 0.4, 0.4).
  • Change the Item Name in SC_PickItem to "Cylinder" and the Item Preview to an image of a cylinder

Coding a Simple Inventory System With UI Drag and Drop in Unity (8)

For Sphere Item:

  • Duplicate a "SimpleItem" Object and name it "SimpleItem 3"
  • Remove the child Cube and create a new Sphere (GameObject -> 3D Object -> Sphere). Move it inside "SimpleItem 3" and Scale it to (0.4, 0.4, 0.4).
  • Change the Item Name in SC_PickItem to "Sphere" and Item Preview to an image of a sphere

Coding a Simple Inventory System With UI Drag and Drop in Unity (9)

Now Save each item into Prefab:

Coding a Simple Inventory System With UI Drag and Drop in Unity (10)

Coding a Simple Inventory System With UI Drag and Drop in Unity (11)

The items are now ready.

The last step is to set up the Inventory System:

  • Attach SC_InventorySystem to "Player" Object
  • Assign a Crosshair Texture variable (You can use the image below or get high-quality crosshair textures from here):

Coding a Simple Inventory System With UI Drag and Drop in Unity (12)

  • Assign SC_CharacterController to the "Player Controller" variable in SC_InventorySystem
  • For the "Available Items" assign previously created item Prefabs (Note: This should be Prefab instances from the Project view and not Scene objects):

Coding a Simple Inventory System With UI Drag and Drop in Unity (13)

The inventory system is now ready, let's test it:

Coding a Simple Inventory System With UI Drag and Drop in Unity (14)

Everything works as expected!

Coding a Simple Inventory System With UI Drag and Drop in Unity (2024)

References

Top Articles
Latest Posts
Article information

Author: Domingo Moore

Last Updated:

Views: 5818

Rating: 4.2 / 5 (73 voted)

Reviews: 80% of readers found this page helpful

Author information

Name: Domingo Moore

Birthday: 1997-05-20

Address: 6485 Kohler Route, Antonioton, VT 77375-0299

Phone: +3213869077934

Job: Sales Analyst

Hobby: Kayaking, Roller skating, Cabaret, Rugby, Homebrewing, Creative writing, amateur radio

Introduction: My name is Domingo Moore, I am a attractive, gorgeous, funny, jolly, spotless, nice, fantastic person who loves writing and wants to share my knowledge and understanding with you.