Ошибка, очевидно, исходит от
inventory.AddItem(new Pickup { itemType = itemType, amount = 1 }, i, itemButton);
и, вероятно, также от
public Inventory()
{
itemList = new List<Pickup>();
}
, он сообщает вам, что именно не так, поэтому я думаю, что это не обсуждается здесь. MonoBehaviour
не может быть создан через new
или иметь конструктор! Единственный способ создать экземпляры - использовать AddComponent
, Instantiate
или конструктор GameObject
.
Чтобы решить эту проблему, вы должны просто не использовать List<Pickup>
, а разделить данные из поведения, например:
public enum ItemType
{
Bow,
Arrow,
Sword,
}
// This will be the data type you pass on and store in your inventory
[Serializable]
public struct PickUpData
{
public ItemType itemType;
public int amount;
}
Затем в инвентаре
public class Inventory : MonoBehaviour
{
public int[] items;
public List<PickUpData> itemList = new List<PickUpData>();
public GameObject[] slots;
// Note: Remove empty Unity message methods they are just overhead
// Note: Inventory is a MonoBehaviour and therefore may not have any constructor!
// Do you need this? itemList is public anyway ...
public List<PickupData> GetItemList()
{
return itemList;
}
public void AddItem(PickUpData item, int i, GameObject itemButton)
{
if (item.IsStackable())
{
var itemAlreadyInInventory = false;
foreach (Pickup InventoryItem in itemList)
{
if(InventoryItem.itemType == item.itemType)
{
InventoryItem.amount += item.amount;
itemAlreadyInInventory= true;
}
}
if(!itemAlreadyInInventory)
{
itemList.Add(item);
items[i] = 1;
Instantiate(itemButton, slots[i].transform, false);
}
}
else
{
itemList.Add(item);
items[i] = 1;
Instantiate(itemButton, slots[i].transform, false);
}
}
}
, а затем в пикапе вместо поля PickUpData
, которое вы можете настроить так же, как прямые поля до, а затем передать его
public class Pickup : MonoBehaviour
{
// This will hold the data you pass on and store in the inventory
// Since the struct is serializable and public this will be initialized with a valid
// reference by default
public PickUpData data;
private Inventory inventory;
private GameObject slots;
public GameObject itemButton;
// Start is called before the first frame update
private void Start()
{
slots = GameObject.FindGameObjectWithTag("Player");
inventory = GameObject.FindGameObjectWithTag("Player").GetComponent<Inventory>();
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Player"))
{
for (int i = 0; i < inventory.items.Length; i++)
{
if (inventory.items[i] == 0)
{
inventory.AddItem(data, i, itemButton);
Destroy(gameObject);
break;
}
}
}
}
public bool IsStackable()
{
switch (itemType)
{
case ItemType.Bow:
case ItemType.Sword:
return false;
// default should always be on the bottom
case ItemType.Arrow:
default:
return true;
}
}
}