Я получаю предупреждение: вы пытаетесь создать MonoBehaviour, используя ключевое слово 'new' - PullRequest
0 голосов
/ 26 мая 2020

Полное сообщение предупреждения:

Вы пытаетесь создать MonoBehaviour, используя ключевое слово 'new'. Это не разрешено. MonoBehaviours можно добавить только с помощью AddComponent (). В качестве альтернативы, ваш скрипт может наследовать от ScriptableObject или вообще не иметь базового класса

Я пытаюсь провести инвентаризацию своей игры, я следовал коду из BLACKTHORNPROD, но нет элемента стека, поэтому я пытаюсь изменить код. Это скрипт инвентаризации

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Inventory : MonoBehaviour
{
    public int[] items;

    public List<Pickup> itemList;
    public GameObject[] slots;
    void start(){

    }
    void Update(){

        // Debug.Log(itemList); 
    }

    public Inventory(){
        itemList = new List<Pickup>();
    }
    public List<Pickup> GetItemList(){
        return itemList;
    }

    public void AddItem(Pickup item, int i, GameObject itemButton){
        if (item.IsStackable()){
            bool 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);
        }
    }
}

Скрипт вывоза:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Pickup : MonoBehaviour
{


    public ItemType itemType;
    public int amount;
    // public ItemType[] itemTypes;
    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(new Pickup { itemType = itemType, amount = 1 }, i, itemButton);
                    Destroy(gameObject);
                    break;

                }
            }
        }


    }

    public bool IsStackable()
    {
        switch (itemType)
        {
            default:
            case ItemType.Arrow:
                return true;

            case ItemType.Bow:
            case ItemType.Sword:
                return false;
        }
    }
    public enum ItemType
    {
        Bow,
        Arrow,
        Sword,

    }
}

Ответы [ 2 ]

0 голосов
/ 26 мая 2020

Насколько я понимаю, проблема в следующей строке:

itemList = new List<Pickup>();

Вы должны понимать, что если вы добавите MonoBehaviour в класс, вы не сможете создать их с помощью «нового» (как сообщает предупреждающее сообщение ). Это помогает думать о классе PickUp как о UI-элементе.

0 голосов
/ 26 мая 2020

Ошибка, очевидно, исходит от

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;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...