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

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

问题描述

完整的警告信息:

您正在尝试使用new"关键字创建 MonoBehaviour.这是不允许的.MonoBehaviours 只能使用 AddComponent() 添加.或者,您的脚本可以继承自 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 实例化,也不能有任何构造函数!创建实例的唯一方法是使用 AddComponentInstantiate 或通过 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 而是将数据与行为分开,例如:

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

然后在 Pickup 中有一个 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天全站免登陆