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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Best way to save item in inventory

Discussion in 'Scripting' started by Naografix, Sep 27, 2016.

  1. Naografix

    Naografix

    Joined:
    Sep 16, 2014
    Posts:
    16
    Hello,

    I want to know what is the best way to save item in Inventory.

    This is my way :
    I have 2 controller : BagController (it work with the Real Scene and Object)
    And InventoryController(it work with the interface)

    In fact, when I take item with E, i gonna send this Object to my InventoryController and I gonna diplay it in my interface.

    But i want to delete it in my scène, it's normal i think aha

    So i do this : Destroy(item) (item is gameobject)

    But when I Destroy it, it Will be destroyed in my InventoryController and my interface too...

    So i want to know what is the best way to resolve this.

    (my InventoryController have a list of Gameobject called Slots and these items are a slot prefab. A slot have in property a item Type (like weapon etc))


    Thanks


    I share my code :


    BagController (GetObject is called when I press E)
    Code (CSharp):
    1. public void GetObject(GameObject item)
    2. {
    3.         var inventory = GameObject.FindGameObjectWithTag("Inventory");
    4.      
    5.         inventory.GetComponent<InventoryController>().GetItem(item);
    6.         Destroy(item);
    7. }
    InventoryController
    Code (CSharp):
    1. public void GetItem(GameObject item)
    2. {
    3.        var itemMother = GetItemMotherScript(item);
    4.  
    5.         foreach (var slot in _slots)
    6.         {
    7.                var selectedItem = slot.GetComponent<SlotController>().Item;
    8.                if (selectedItem == null)
    9.                {
    10.                       slot.GetComponent<SlotController>().Item = itemMother;
    11.                       break;
    12.                }
    13.         }
    14. }
     
    Last edited: Sep 28, 2016
  2. Naografix

    Naografix

    Joined:
    Sep 16, 2014
    Posts:
    16
    I share my code.
     
  3. Naografix

    Naografix

    Joined:
    Sep 16, 2014
    Posts:
    16
    Need help ;)
     
  4. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,496
    It sounds like perhaps you're not going about your item management in the way you want to use it. I'm assuming by "delete object" you mean to delete just the model in the scene that's associated with the Item in the inventory list? In which case you could simply have code in the Item component that deletes only the model from the scene when unequipped, and respawns it when equipped. So only the equipped items from your inventory have a model spawned currently.
     
  5. Naografix

    Naografix

    Joined:
    Sep 16, 2014
    Posts:
    16
    I see, but it is really proper to do that ? To just let the object on the ground and for example, do setActive(false) ?

    Imagine if i have 100 players with 30 objects in them bag
     
  6. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,496
    I wasn't say to set it's active state, I said to delete the model (Destroy). Have the script for and item manage the existence of the model. Or better yet have just your inventory script manage it. Your item components should merely contain a reference to the model, when the inventory equips an item, it Instantiate's the object reference in that item component. And when it's unequipped it destroy's just that instantiated object and leaves the item component alone.
     
  7. Naografix

    Naografix

    Joined:
    Sep 16, 2014
    Posts:
    16
    Yes i saw you said destroy the model, but it's the same way finally, we don't destroy the gameobject completly :/
     
  8. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,496
    Destroying the model is the important part, it's what takes up significant memory. (But, when they are SetActive(false) they aren't taking up any significant processing since objects can't update themselves while inactive). You don't have to worry about having even a few hundred or thousand empty objects with an item script on them that are doing nothing in your inventory.

    You want information about each inventory item to be available, yet you don't want any data present in the scene to represent those items... You need some sort of information kept in the scene to represent them.
     
  9. Naografix

    Naografix

    Joined:
    Sep 16, 2014
    Posts:
    16
    Super ! Really thank you Invertex :), i'm going to do that :D
     
  10. Naografix

    Naografix

    Joined:
    Sep 16, 2014
    Posts:
    16
    @Invertex, when you said : destroy the model, you speak about the mesh renderer ?
     
  11. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,496
    No, I mean that your AK47 and item scripts in general shouldn't be placed directly on the model game object, the model should become a child game object that you can Destroy without destroying the item script. Just have a variable in your Item script that keeps a reference to the model asset and Instantiate it as a child when you need it and store it in a "GameObject model;" variable in the item script. Then afterwards when you want to get rid of the model, you just Destroy(model); in the Item script.
     
  12. Naografix

    Naografix

    Joined:
    Sep 16, 2014
    Posts:
    16
    Ho i see.
    Something like this :



    EmptyGameObject have the script


    And the model :


    With the TAG Item for my raycast (to get item)
     
  13. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,496
    Using Tag isn't a good way to go about it since you could have multiple objects in the scene which are tagged Item. Instead, when you Instantiate() the model as the child, have a variable to assign it to in your item script.

    Code (csharp):
    1. [SerializeField]GameObject prefabModel; //Drag your AK47 model from Assets folder onto this inspector slot
    2. GameObject instanceModel;
    3.  
    4. void SpawnItemModel()
    5. {
    6.     instanceModel = Instantiate(prefabModel, transform) as GameObject; //Spawn our prefab model and set it's parent as this object.
    7. }
    Now you have your reference to the spawned object and can do whatever you want, like instanceModel.transform.position = whatever.
     
    Last edited: Sep 29, 2016
  14. Naografix

    Naografix

    Joined:
    Sep 16, 2014
    Posts:
    16
    I use tag [Item] to say to my raycast : if you press E and the tag of the gameobject is Item, then you can get it.

    But ok, thank you !