我收到警告:您正在尝试使用'new'关键字创建MonoBehaviour [英] im getting the warning: You are trying to create a MonoBehaviour using the 'new' keyword

查看:53
本文介绍了我收到警告:您正在尝试使用'new'关键字创建MonoBehaviour的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

完整警告消息:

您正在尝试使用'new'关键字创建MonoBehaviour.这是不允许的.只能使用AddComponent()添加MonoBehaviours.另外,您的脚本可以继承自ScriptableObject或根本不继承基类

You are trying to create a MonoBehaviour using the 'new' keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all

我正在尝试对游戏进行盘点,我遵循了BLACKTHORNPROD的代码,但是没有堆栈项目,因此我试图修改代码.这是库存脚本

Im trying to make an inventory to my game i followed the code from BLACKTHORNPROD but there is no stack item so i'm trying to modify the code. This is the Inventory script

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,

    }
}

推荐答案

错误显然来自

inventory.AddItem(new Pickup { itemType = itemType, amount = 1 }, i, itemButton);

,也许也来自

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

它告诉您确切的问题是什么,所以我想这不是问题. MonoBehaviour 可能无法通过 new 实例化,也没有任何构造函数!创建实例的唯一方法是使用 AddComponent Instantiate 或通过 GameObject 构造函数.

it tells you exactly what is wrong so I guess that is not in question here. MonoBehaviour may not be instantiate via new nor have any constructor! The only way to create instances is by either using AddComponent, Instantiate or via the GameObject constructor.

要解决此问题,您不应仅使用 List< Pickup> ,而应将数据与行为分开,例如:

To solve this you should simply not use a List<Pickup> but rather separate the data from the behavior e.g.:

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 字段,您可以将其配置为与之前的直接字段相同,然后将其传递给

and then in the Pickup instead have a field of PickUpData which you can configrue just the same as the direct fields before and then pass it on

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;
        }
    }
}

这篇关于我收到警告:您正在尝试使用'new'关键字创建MonoBehaviour的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆