- Home /
You are trying to create a MonoBehaviour using the 'new' keyword. This is not allowed.
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
I am trying to connect these two scripts and I don't know which one this error is for. The full error is: 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 UnityEngine.MonoBehaviour:.ctor() ItemClass:.ctor() inventoryV1:.ctor()
Here are the two scripts
sing UnityEngine; using System.Collections;
public class ItemClass : MonoBehaviour { //DECLARE ITEMS HERE //MUST BE PUBLIC
//DECLARE ICONS HERE
//MUST BE STATIC AND PUBLIC
public class ItemCreatorClass
{
string name;
string description;
int id;
int damage;
int speed;
int weight;
int hungerEffect;
int thirstEffect;
int stackAmount;
Texture2D icon;
public ItemCreatorClass(int ide,string nam, string des, int dam, int spe, int wei, int hun, int thi, int sta, Texture2D ico)
{
id = ide;
name = nam;
description = des;
damage = dam;
speed = spe;
weight = wei;
hungerEffect = hun;
thirstEffect = thi;
stackAmount = sta;
icon = ico;
}
}
}
using UnityEngine;
using System.Collections.Generic;
public class inventoryV1 : MonoBehaviour {
public static bool inventoryOn = false;
//GUI FONT AND SIZE
private Vector2 windowPosition = new Vector2(300,0);
private Vector2 windowSize = new Vector2(745, 750);
private Vector2 closePosition = new Vector2(705,9);
private Vector2 closeSize = new Vector2(24,24);
private Vector2 inventoryTitlePosition = new Vector2(245,11);
private Vector2 inventoryTitleSize = new Vector2(125,50);
private Vector2 playerTitlePosition = new Vector2(17,11);
private Vector2 playerTitleSize = new Vector2(100,50);
private Vector2 craftingTitlePosition = new Vector2(17,414);
private Vector2 craftingTitleSize = new Vector2(125,40);
//Dictionary
static public Dictionary<int, string> inventoryNameDictionary;
//WINDOW TEXTURES
public Texture inventoryWindow;
//BUTTON TEXTURES
public Texture closeInventory;
public Texture inventorySlot;
//ACCESS CLASSES
ItemClass itemObject = new ItemClass();
void Update ()
{
//ON OR OFF
if (Input.GetKeyUp (KeyCode.Tab))
{
if (inventoryOn == false)
{
inventoryOn = true;
}
else if (inventoryOn == true)
{
inventoryOn = false;
}
}
}
//GUI AND FUNCTIONALITY
void OnGUI()
{
if (inventoryOn == true)
{
GUILayout.BeginArea(new Rect (windowPosition.x, windowPosition.y, windowSize.x, windowSize.y), inventoryWindow);
//Close Button
if (GUI.Button (new Rect (closePosition.x, closePosition.y, closeSize.x, closeSize.y), closeInventory)) {
inventoryOn = false;
}
//INVENTORY SECTION TITLES
GUI.Label(new Rect(inventoryTitlePosition.x, inventoryTitlePosition.y, inventoryTitleSize.x, inventoryTitleSize.y),"Inventory");
GUI.Label (new Rect( playerTitlePosition.x, playerTitlePosition.y, playerTitleSize.x, playerTitleSize.y), "Player");
GUI.Label(new Rect(craftingTitlePosition.x, craftingTitlePosition.y, craftingTitleSize.x, craftingTitleSize.y), "Crafting Menu");
//INVENTORY SLOTS
//FIRST ROW
GUI.Button (new Rect (270, 50, 70, 70), inventoryNameDictionary[0]);
GUI.Button (new Rect (345, 50, 70, 70), inventoryNameDictionary[1]);
GUI.Button (new Rect (420, 50, 70, 70), inventoryNameDictionary[2]);
GUI.Button (new Rect (495, 50, 70, 70), inventoryNameDictionary[3]);
GUI.Button (new Rect (570, 50, 70, 70), inventoryNameDictionary[4]);
GUI.Button (new Rect (645, 50, 70, 70), inventoryNameDictionary[5]);
//SECOND ROW
GUI.Button (new Rect (270, 125, 70, 70), inventoryNameDictionary[6]);
GUI.Button (new Rect (345, 125, 70, 70), inventoryNameDictionary[7]);
GUI.Button (new Rect (420, 125, 70, 70), inventoryNameDictionary[8]);
GUI.Button (new Rect (495, 125, 70, 70), inventoryNameDictionary[9]);
GUI.Button (new Rect (570, 125, 70, 70), inventoryNameDictionary[10]);
GUI.Button (new Rect (645, 125, 70, 70), inventoryNameDictionary[11]);
//THIRD ROW
GUI.Button (new Rect (270, 200, 70, 70), inventoryNameDictionary[12]);
GUI.Button (new Rect (345, 200, 70, 70), inventoryNameDictionary[13]);
GUI.Button (new Rect (420, 200, 70, 70), inventoryNameDictionary[14]);
GUI.Button (new Rect (495, 200, 70, 70), inventoryNameDictionary[15]);
GUI.Button (new Rect (570, 200, 70, 70), inventoryNameDictionary[16]);
GUI.Button (new Rect (645, 200, 70, 70), inventoryNameDictionary[17]);
//FOURTH ROW
GUI.Button (new Rect (270, 275, 70, 70), inventoryNameDictionary[18]);
GUI.Button (new Rect (345, 275, 70, 70), inventoryNameDictionary[19]);
GUI.Button (new Rect (420, 275, 70, 70), inventoryNameDictionary[20]);
GUI.Button (new Rect (495, 275, 70, 70), inventoryNameDictionary[21]);
GUI.Button (new Rect (570, 275, 70, 70), inventoryNameDictionary[22]);
GUI.Button (new Rect (645, 275, 70, 70), inventoryNameDictionary[23]);
GUILayout.EndArea ();
//ARMOR SLOTS
//DICTIONARY
inventoryNameDictionary = new Dictionary<int, string>()
{
//THE LINE BENEATH THIS COMMENT HAS THE ERROR
{0, string.Empty},
{1, string.Empty},
{2, string.Empty},
{3, string.Empty},
{4, string.Empty},
{5, string.Empty},
{6, string.Empty},
{7, string.Empty},
{8, string.Empty},
{9, string.Empty},
{10, string.Empty},
{11, string.Empty},
{12, string.Empty},
{13, string.Empty},
{14, string.Empty},
{15, string.Empty},
{16, string.Empty},
{17, string.Empty},
{18, string.Empty},
{19, string.Empty},
{20, string.Empty},
{21, string.Empty},
{22, string.Empty},
{23, string.Empty}
};
}
}
}
Answer by Hoeloe · Mar 02, 2014 at 10:08 PM
The problem is, as has been said, this line:
ItemClass itemObject = new ItemClass();
Unity does not allow you to instantiate anything inheriting from the MonoBehaviour class using the new
keyword. This seems a bit odd, until you consider what the MonoBehaviour class is.
MonoBehaviours are scripts that are attached to an object in the scene, and run in the scene as long as the object they are attached to is active. MonoBehaviours HAVE to be attached to something, or they won't be able to function properly. When you use new
, you are basically saying: "Please make one of these, store it somewhere, and give me a link to it". What you don't tell it is: "Also attach it to the place I'm calling it from". The reason this isn't done is because the concept of attaching things to objects is Unity specific, while the keyword new
is general to C#, and so has no concept of Unity constructions - it can't physically do this.
So how DO you specify what to attach it to? Well, Unity provides it's own method for this - namely GameObject.AddComponent()
. What this does is create a new script, of type T, and add it to the specified GameObject. So, if you have a GameObject called obj
and a script called MyScript
, you can dynamically add the script to your object by, instead of doing this:
MyScript script = new Script();
Which would, hypothetically, give you a script floating in space, not attached to anything, you can do this:
MyScript script = obj.AddComponent<MyScript>();
This will add a new MyScript
component to obj
, and then will set the variable script
to that component, so you can then access it.
Hopefully, you can see why this issue occurs, and what you can do to solve it, now.
As a side note, there is a non-generic form of AddComponent
, which doesn't use the triangle brackets notation, and ins$$anonymous$$d takes the class name as a string. I would strongly recommend using generics wherever possible - they are far tidier, potentially faster, and easier for the debugger to find problems with.
For some reason even though I declared the obj public, it won't show it in the inspector. Any help with why that is happening?
A number of things could be causing that, one would be that it is not of a type that Unity can serialise (if its type is GameObject
, this won't be a problem), another is that it has to be defined at the class level, not inside a method. It doesn't have to be defined there, but it has to at least be declared at that point. Another likely solution is that your code has compiler errors (that is, errors that are preventing the code from compiling, not just from running, check the console window), which will prevent it from updating the script.
Thank you. It is probably because I didn't use the actual values for the Items
I think a more convenient way is to remove the $$anonymous$$onobehaviour
extension. To add a script to a game object just to go the unity way without needing the script in the object sounds confusing to me. But thanks for your explanation, now I understand why the warnings came! :)
Answer by robertbu · Mar 02, 2014 at 07:30 PM
The issue is line 33:
ItemClass itemObject = new ItemClass();
The solution is to remove 'Monobehaviour' from the class declaration so this:
public class ItemClass : MonoBehaviour { //DECLARE ITEMS HERE //MUST BE PUBLIC
becomes this:
public class ItemClass { //DECLARE ITEMS HERE //MUST BE PUBLIC
Now it says Null Reference Exception : Object reference not set to an instance of an object Why is this happening and how can I fix it
It doesn't say on what line. t just says for the two scripts I put above.
If you double click on the error in the console, what script and line does it take you to? Can you past the error from the Console into a comment?
Answer by DetaPlayFounder · May 25 at 08:30 PM
Resurrecting this for those who believe this is an issue.
Just because its a unity warning does not mean your code is incorrect.
To list an example outside of your case, using async Tasks correctly will inevitably prompt a Unity Warning indicating a method was not "awaited". For some scenarios this warning is true, but in cases of using parallelism Unity is wrong on this part.
As stated previously, writing "new" on a class that inherits the Monobehavior Class will always prompt a warning. The warning is not a problem. If your intention is to initialize and set reference to a script without creating a GAMEOBJECT, calling "new" is completely fine. ########################################################################### The current voted Answer is suggesting to use AddComponent. Although this gets the job done the "UNITY WAY", it is wasteful and creates a physical gameobject in your scene with your Added Component.
If your intention is to initialize and set reference to a script without creating a GAMEOBJECT, calling "new" is completely fine.
By essence, MonoBehaviours (more generally Components) are meant to be attached to gameObjects. If your class instance is not meant to be attached to a GameObject, there it shouldn't inherit from MonoBehaviour / Component in the first place.
Remember that you can manipulate Unity's objects in a plain C# class if needed.
public class MyClass
{
private GameObject gameObject;
public MyClass(GameObject gameObject)
{
this.gameObject = gameObject;
}
public void Foo()
{
gameObject.SetActive(true);
gameObject.transform.Translate(1, 0, 0);
gameObject.GetComponent<MyComponent>().DoSomething();
}
}
Answer by Vardan Meliksetyan · Mar 02, 2014 at 07:30 PM
Hello, if you want to call class from other file or other script it is easy. All script classes must inheritance from MonoBehaviour, and file and class name must be the same. You can make class members, or methods static and call "Classname"."Method or member name".
Answer by PsychoHead · Mar 02, 2014 at 07:43 PM
I think your question is formatted oddly, the problem however is the line
ItemClass itemObject = new ItemClass();
While this is the standard way of instantiating a class in C#, Unitys MonoBehaviours have their own way of instantiating, since scripts are components in Unity. gameObject.AddComponent("ItemClass"); Your ItemClass class is a MonoBehavior. ( public class ItemClass : MonoBehaviour )