我收到警告:您正在尝试使用'new'关键字创建MonoBehaviour [英] im getting the warning: You are trying to create a MonoBehaviour using the 'new' keyword
问题描述
完整警告消息:
您正在尝试使用'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屋!