- Home /
 
Items not destroying.
Hello, I just almost got everything in a crafting system complete :). I just have one more bug, when I craft something the items used do not delete! How do I fix this, what am I doing wrong!
Code:
 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 using System.Linq;
 
 public class PlayerInventory : MonoBehaviour {
 
     public List<Item> MyItems = new List<Item>();
 
     public Weapon weapon1;
     public Weapon weapon2;
 
     public Clothes MyClothes;
 
     public PlayerWeaponManager pwm;
     public PlayerClothesManager pcm;
 
     public void AddWeapon(Weapon we){
         if(networkView.isMine){
             if(we.weslot == 1){
                 weapon1 = we;
             }
             if(we.weslot == 2){
                 weapon2 = we;
             }
             pwm.SwitchWeapon(we.weslot);
         }
 
     }
 
     void OnGUI(){
         if(GUILayout.Button("Add wood")){
             MyItems.Add(Item.Wood());
         }
         if(GUILayout.Button("Craft wood-wall")){
             Craft(Craftable.WoodenWall());
         }
     }
 
     public void AddClothes(Clothes _clothes){
         MyClothes = _clothes;
     }
 
 
 
     public void AddItem(Item added){
         if(networkView.isMine){
             MyItems.Add (added);
         }
     }
 
 
     /*
      * 
      * Basic Crafting!
      * 
      */
 
 
     public void Craft(Craftable recipe){
         bool b = CheckItems (recipe.InputItems);
         if (b) {
             foreach(Item it in recipe.InputItems){
                 MyItems.Remove(it);
             }
             MyItems.Add(recipe.output);
         }
         else{
             Debug.Log("Not enough material!");
         }
     }
 
     /*public bool CheckIfItemsInInventory(List<Item> check){
         return !check.Except(MyItems).Any();
     }*/
     public bool CheckItems(List<Item> check) {
         foreach(Item inventoryItem in MyItems) {
             if (check.Contains(inventoryItem)) {
                 check.Remove(inventoryItem);
                 if(check.Count == 0) {
                     return true;
                 }
             }
         }
         return false;
     }
 
 
     //This crafting system is not used anymore.
 
     /*public void Craft(Craftable recipe){
         Item _1 = new Item();
         Item _2 = new Item();
         Item _3 = new Item();
         if (CheckForItemsByName(myItems,recipe.input1.itname,out _1)) {
             if(CheckForItemsByName(myItems,recipe.input2.itname,out _2)){
                 if(recipe.input3.itname.Length > 1){
                     if(CheckForItemsByName(myItems,recipe.input3.itname,out _3)){
                     myItems.Add(recipe.output);
                     myItems.Remove(_1);
                     myItems.Remove(_2);
                     myItems.Remove(_3);
                     return;
                 }
                 }
                 else{
                     myItems.Add(recipe.output);
                     myItems.Remove(_1);
                     myItems.Remove(_2);
                     return;
                 }
             }
         }
         else{
             Debug.Log("Not enough material!");
         }
     }*/
 
     /*public bool CheckForItemsByName(List<Item> _list, string lookfor, out Item found)
     {
         foreach (Item it in _list) {
             if(it.itname == lookfor){
                 found = it;
                 return true;
             }
         }
         found = null;
         return false;
     }*/
 
 }
 using System.Collections;
 
 [System.Serializable]
 public class Item {
 
     public string itname;
     public string ittype;
     public float itvalue;
     public float itdur;
 
     public override bool Equals(object other) {
         if (other.GetType() != typeof(Item)) return false;
         return ((Item)other).itname == this.itname;
     }
 
     public static Item Wood(){
         Item i = new Item ();
         i.itname = "Wood";
         i.ittype = "Craft";
         i.itvalue = 1;
         i.itdur = 1;
         return i;
     }
 
     public static Item WoodenWall(){
         Item i = new Item ();
         i.itname = "Wooden Wall";
         i.ittype = "Build";
         i.itvalue = 1;
         i.itdur = 1;
         return i;
     }
 
 }
 
              I don't see any DestroyImmediate() lines.. How exactly are you trying to destroy items?
what do you mean "Destroying" ??? if you want to destroy a game object (remove it from scene) then use Destroy(objectName) otherwise you need explain your problem a little bit more
@Aladine , Don't always use Destroy() though, if you have functions happening later in your script that rely on knowing if an object exists or not, then you want to use DestroyImmediate(object,true);, so that it's references are set to null immediately, not after the frame is finished.
@Invertex , Yes i know that but it's a bit "complicated" subject to talk about in this topic and since he want to destory, Destroy() is the first function i thought about, thanx anyway ^^
Answer by oatsbarley · Jan 26, 2014 at 10:41 AM
The problem is caused by CheckItems() removing items from the list passed to it. Because it gets passed a reference to the list, any changes made will affect recipe.InputItems. So by the time you get to this section:
 foreach(Item it in recipe.InputItems) {
       MyItems.Remove(it);
 }
 MyItems.Add(recipe.output);
 
               recipe.InputItems is already empty and so nothing is removed from MyItems.
Inside CheckItems() you need to make a copy of the list passed to it like so:
 var copy = new List<Item>(check);
 
               And then use the copy inside the foreach loop instead of the original.
Your answer
 
             Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
A node in a childnode? 1 Answer
Pathfinding through pairs of connections 2 Answers
generic list, swapping equipment errors but not always? 1 Answer