Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Resolved Issue with instantiate function from inventory system and database

Discussion in 'Scripting' started by FloFraiz, Jul 26, 2023.

  1. FloFraiz

    FloFraiz

    Joined:
    Aug 6, 2018
    Posts:
    4
    Hello,
    I need help to understand something.
    I'm creating an inventory system with an object database and a drag&drop system.
    Everything is working fine, I've managed to change the location of objects in the inventory, and even delete them from the inventory when the object is dropped out of the inventory.
    Since I added a function to instantiate them in the world when the object is dropped out of the inventory, out of 14 objects that are configured in the same way (each has its own scriptableObject and prefab), 2 of them don't remove themselves from the inventory, either they return to their place before the drag or they go to the first slot if it's free.
    I can't figure out why it doesn't work with those 2 only items.
    A video to show you:


    My function to remove from inventory :

    Code (CSharp):
    1. public void RemoveItem(Item _item)
    2.     {
    3.         for(int i = 0; i < Container.Items.Length; i++)
    4.         {
    5.             if(Container.Items[i].item == _item)
    6.             {                  
    7.                InstantiateItem(_item);
    8.                Container.Items[i].UpdateSlot(-1, null, 0);
    9.             }
    10.         }
    11.     }
    And the one to instantiate:
    Code (CSharp):
    1. private void InstantiateItem(Item _item)
    2.     {
    3.         // Obtenez le prefab de l'objet à partir de votre base de données d'objets
    4.         GameObject itemPrefab = database.GetItem[_item.Id].prefab;
    5.  
    6.         // Vérifiez si le prefab est null
    7.         if (itemPrefab == null)
    8.         {
    9.             Debug.Log("Prefab is null");
    10.             return;
    11.         }
    12.         else {Debug.Log("Prefab found: " + itemPrefab.name);}
    13.        
    14.  
    15.         // Obtenez la position du joueur
    16.         GameObject player = GameObject.FindWithTag("Player"); // Assurez-vous que votre joueur a le tag "Player"
    17.         Vector3 playerPosition = player.transform.position;
    18.  
    19.         // Instanciez l'objet à la position du joueur
    20.         GameObject newItem = Instantiate(itemPrefab, playerPosition, Quaternion.identity);
    21.  
    22.         // Vérifiez si l'objet instancié est null
    23.         if (newItem == null)
    24.         {
    25.             Debug.Log("Instantiated object is null");
    26.             return;
    27.         }
    28.         else {Debug.Log("Object instantiated: " + newItem.name);}
    29.     }
    If anyone has an explanation, I'd be delighted.
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    3,899
    What does UpdateSlot() do? Could you show that code too?

    What is Item? A class? Inheriting from what other class?

    I couldn‘t read the logs in the console, would help if you said what it prints when an item fails to instatiate.
     
  3. FloFraiz

    FloFraiz

    Joined:
    Aug 6, 2018
    Posts:
    4
    Hi,

    In fact, "Item" is a class inherent to another script in order to store scriptableObjects and their datas in my database which is also a scriptableObject.

    DatabaseScript:
    Code (CSharp):
    1. [CreateAssetMenu(fileName ="New Item Database", menuName = "Inventory System/Items/Database")]
    2. public class ItemDataBaseObject : ScriptableObject, ISerializationCallbackReceiver
    3. {
    4.     public ItemObject[] Items;
    5.     public Dictionary<int, ItemObject> GetItem = new Dictionary<int, ItemObject>();
    6.  
    7.     public void OnBeforeSerialize()
    8.     {
    9.         GetItem = new Dictionary<int, ItemObject >();
    10.     }
    11.  
    12.     public void OnAfterDeserialize() //Après le fin de l'instance
    13.     {
    14.         for (int i = 0 ; i < Items.Length; i++)
    15.         {
    16.             Items[i].Id = i;
    17.             GetItem.Add(i, Items[i]);
    18.         }
    19.     }
    20. }
    ItemObject Script :
    Code (CSharp):
    1. public abstract class ItemObject : ScriptableObject
    2. {
    3.     public int Id;
    4.     public GameObject prefab;
    5.     public Sprite UIDisplay;
    6.     public ItemType type;
    7.     [TextArea(15,20)]
    8.     public string description;
    9.     public ItemBuff[] buffs;
    10.  
    11.     public Item CreateItem()
    12.     {
    13.         Item newItem = new Item(this);
    14.         return newItem;
    15.     }
    16. }
    17.  
    18. [System.Serializable]
    19. public class Item
    20. {
    21.     public string Name;
    22.     public int Id;
    23.     public ItemBuff[] buffs;
    24.     public Item(ItemObject item)
    25.     {
    26.         Name = item.name;
    27.         Id = item.Id;
    28.         buffs = new ItemBuff[item.buffs.Length];
    29.         for(int i = 0; i < buffs.Length; i++)
    30.         {
    31.             buffs[i] = new ItemBuff(item.buffs[i].min, item.buffs[i].max);
    32.             buffs[i].attribute = item.buffs[i].attribute;
    33.         }
    34.     }
    35. }
    Concerning UpdateSlot() here, this is the function that allows me to update the slots created in my UI depending if it's empty or not, which item is in and how many of them are stored.
    The class Inventory shown below is also known as Container in the RemoveSlot function in the script who manages the UI

    Code (CSharp):
    1.  
    2. public class InventoryObject : ScriptableObject
    3. {
    4.     public Inventory Container;
    5. }
    6. ...
    7. [System.Serializable]
    8. public class Inventory
    9. {
    10.     public InventorySlot[] Items = new InventorySlot[42];
    11. }
    12.  
    13. [System.Serializable]
    14. public class InventorySlot
    15. {
    16.     public int ID = -1;
    17.     public Item item;
    18.     public int amount;
    19.  
    20.     public InventorySlot()
    21.     {
    22.         ID = -1;
    23.         item = null;
    24.         amount = 0;
    25.     }
    26.  
    27.     public void UpdateSlot(int _id, Item _item, int _amount)
    28.     {
    29.         ID = _id;
    30.         item = _item;
    31.         amount = _amount;
    32.     }
    33.  
    34.     public InventorySlot(int _id, Item _item, int _amount)
    35.     {
    36.         ID = _id;
    37.         item = _item;
    38.         amount = _amount;
    39.     }
    40.  
    41.     public void AddAmount(int value)
    42.     {
    43.         amount += value;
    44.     }
    45. }
    Finally, concerning the log, if we take the Pants object as an example, it prints "Prefab found: Man_Pants_Mesh" & "Object instantiated: Man_Pants_Mesh(Clone)" ( line 12 & 28 of InstatiateItem() ) even if, we can clearly see that the item remains stored in the inventory and displayed in the UI.

    The weird thing is that only 2 objects are concerned while they are configured the same as the other 12.
    I tried to make them again from zero, same result...

    I hope I have provided as much detail as possible to help.
     
    Last edited: Jul 27, 2023