scriptable object for items
using UnityEngine;
public enum ItemType { Material, Food, Drink}
[CreateAssetMenu(fileName = "itemSO", menuName = "Scriptable Objects/itemSO")]
public class itemSO : ScriptableObject
{
public string itemName;
public Sprite icon;
public ItemType type;
public int maxStack = 99;
}
create scriptable object
Find 3 images and models for apple, orange, grape
change the texture type to sprite and the sprite mode to single
Create 3 scriptable object for a apple, orange and grape
//write script for inventory
using System.Collections.Generic;
using UnityEngine;
public class Inventory : MonoBehaviour
{
// Start is called once before the first execution of Update after the MonoBehaviour is created
public Dictionary<itemSO, int> items = new Dictionary<itemSO, int>();
public void AddItem(itemSO item, int amount)
{
if (!items.ContainsKey(item))
items[item] = 0;
items[item] += amount;
Debug.Log($"Picked up {item.itemName}. Now have {items[item]}");
}
public bool HasItem(itemSO item, int amount)
{ return items.ContainsKey(item) && items[item]>=amount; }
public void RemoveItem(itemSO item, int amount)
{
if(items.ContainsKey(item))
{
items[item] -= amount;
if (items[item]<= 0)
items.Remove(item);
}
}
}
Pickupitem script, attach your script to your items, apple, grape, orange
using UnityEngine;
public class PickupItem : MonoBehaviour
{
public Inventory inventory;
public itemSO item;
public void OnTriggerEnter(Collider other)
{
Debug.Log("collide" + other.name);
if(other.CompareTag("Player"))
{
inventory.AddItem(item, 1);
Destroy(gameObject);
}
}
}
Make sure you check the isTrigger button.
and your player have "player" tag
Add apple, orange, grape model to your game scene
attach the pickup item script to your apple, grape and orange
update your inventory script
using NUnit.Framework.Interfaces;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class Inventory : MonoBehaviour
{
// Start is called once before the first execution of Update after the MonoBehaviour is created
public Dictionary<itemSO, int> items = new Dictionary<itemSO, int>();
public Transform inventoryPanel;
public GameObject inventorySlotPrefab;
public void AddItem(itemSO item, int amount)
{
if (!items.ContainsKey(item))
items[item] = 0;
items[item] += amount;
Debug.Log($"Picked up {item.itemName}. Now have {items[item]}");
refreshUI();
foreach(var no in items)
{
Debug.Log(items);
}
}
public bool HasItem(itemSO item, int amount)
{ return items.ContainsKey(item) && items[item]>=amount; }
public void RemoveItem(itemSO item, int amount)
{
if(items.ContainsKey(item))
{
items[item] -= amount;
if (items[item]<= 0)
items.Remove(item);
}
}
public void refreshUI()
{
foreach (Transform child in inventoryPanel)
{
Destroy(child.gameObject);
}
foreach (var entry in items)
{
itemSO item = entry.Key;
int count = entry.Value;
GameObject slot = Instantiate(inventorySlotPrefab, inventoryPanel);
Transform iconTransform = slot.transform.Find("icon");
Transform countTransform = slot.transform.Find("count");
if (iconTransform == null || countTransform == null)
{
Debug.LogError("icon or count child not found in slot prefab!");
continue;
}
Image icon = iconTransform.GetComponent<Image>();
TextMeshProUGUI countText = countTransform.GetComponent<TextMeshProUGUI>();
if (icon != null)
{
icon.enabled = true;
icon.sprite = item.icon;
}
if (countText != null)
{
countText.enabled = true;
countText.text = count.ToString();
}
}
}
}
create a canvas for your inventory
Create a panel and rename it as inventory panel
For the name of object should be same like the picture,
Because in our script
Transform iconTransform = slot.transform.Find("icon");
Transform countTransform = slot.transform.Find("count");
Then drag the slot to prefab
In your inventory script there
Remember to add the items
update your inventory script, press I to toggle the inventory UI
using NUnit.Framework.Interfaces;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class Inventory : MonoBehaviour
{
// Start is called once before the first execution of Update after the MonoBehaviour is created
public Dictionary<itemSO, int> items = new Dictionary<itemSO, int>();
public Transform inventoryPanel;
public GameObject inventorySlotPrefab;
public GameObject inventoryGO;
bool inventoryStatus =false;
public void Start()
{
inventoryGO.SetActive(inventoryStatus);
}
private void Update()
{
if(Input.GetKeyDown(KeyCode.I))
{
inventoryStatus = !inventoryStatus;
inventoryGO.SetActive(inventoryStatus);
}
}
public void AddItem(itemSO item, int amount)
{
if (!items.ContainsKey(item))
items[item] = 0;
items[item] += amount;
Debug.Log($"Picked up {item.itemName}. Now have {items[item]}");
refreshUI();
foreach (var no in items)
{
Debug.Log(items);
}
}
public bool HasItem(itemSO item, int amount)
{ return items.ContainsKey(item) && items[item] >= amount; }
public void RemoveItem(itemSO item, int amount)
{
if (items.ContainsKey(item))
{
items[item] -= amount;
if (items[item] <= 0)
items.Remove(item);
}
}
public void refreshUI()
{
foreach (Transform child in inventoryPanel)
{
Destroy(child.gameObject);
}
foreach (var entry in items)
{
itemSO item = entry.Key;
int count = entry.Value;
GameObject slot = Instantiate(inventorySlotPrefab, inventoryPanel);
Transform iconTransform = slot.transform.Find("icon");
Transform countTransform = slot.transform.Find("count");
if (iconTransform == null || countTransform == null)
{
Debug.LogError("icon or count child not found in slot prefab!");
continue;
}
Image icon = iconTransform.GetComponent<Image>();
TextMeshProUGUI countText = countTransform.GetComponent<TextMeshProUGUI>();
if (icon != null)
{
icon.enabled = true;
icon.sprite = item.icon;
}
if (countText != null)
{
countText.enabled = true;
countText.text = count.ToString();
}
}
}
}
go to your project setting change the active input handling to both. then your unity will restart again
update your inventory script, remember to fill in the slot