- Home /
List of Monobehaviour clasess, Editor
I have 2 scripts. SpawnerM2 and SpawnerM2Editor.
First script contains 2 clases:
[System.Serializable]
public class SpawnerM2Single : MonoBehaviour
{
// some variables
void Update ()
{
// some code
}
}
[System.Serializable]
public class SpawnerM2 : MonoBehaviour
{
public List<SpawnerM2Single> single = new List<SpawnerM2Single>();
}
second script:
[CustomEditor(typeof(SpawnerM2))]
public class SpawnerM2Editor : Editor
{
private SerializedObject spawnerM2SO;
private SpawnerM2 mySpawnerM2;
void OnEnable ()
{
spawnerM2SO = new SerializedObject(target);
mySpawnerM2 = (SpawnerM2)target;
}
public override void OnInspectorGUI ()
{
spawnerM2SO.Update();
EditorGUILayout.BeginVertical();
int i = 0;
foreach(SpawnerM2Single sp in mySpawnerM2.single)
{
EditorGUILayout.Foldout(true,"Spawner #" + i);
{
// some code
}
i++;
}
EditorGUILayout.EndVertical();
if (GUILayout.Button("Add spawner"))
{
// ERROR HERE
mySpawnerM2.single.Add(new SpawnerM2Single());
}
if (GUILayout.Button("Remove last spawner") && mySpawnerM2.single.Count > 0)
{
mySpawnerM2.single.RemoveAt(mySpawnerM2.single.Count-1);
}
if(GUI.changed)
{
EditorUtility.SetDirty(target);
EditorUtility.SetDirty(mySpawnerM2);
}
spawnerM2SO.ApplyModifiedProperties();
}
}
I get an error message:
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() SpawnerM2Single:.ctor() SpawnerM2Editor:OnInspectorGUI() (at Assets/Editor/SpawnerM2Editor.cs:57) UnityEditor.DockArea:OnGUI()
How Can I change the code to make it works
Answer by _dns_ · Oct 28, 2014 at 02:26 PM
Hi, to create a MonoBehavior based class you should not use "new SpawnerM2Single()", Unity needs to create the object itself.
You can create a new gameObject and then add Components to it like described here: http://docs.unity3d.com/ScriptReference/GameObject-ctor.html. You can also Instantiate an existing prefab, in the Editor using: http://docs.unity3d.com/ScriptReference/PrefabUtility.InstantiatePrefab.html
Also, btw, you don't need to add [System.Serializable] to a Monobehavior-based class.
I changed it to :
mySpawner$$anonymous$$2Single = (new GameObject("SingleSpawner")).AddComponent<Spawner$$anonymous$$2Single>();
It works, but it creates SingleSpawner GameObject, on my scene, everytime I click component in the inspector
How can I avoid it?
Well, it depends on what you want to do. In Unity, a gameobject is either in the form of a prefab in a file asset, or as an instance in a scene (well, prefabs referenced in a scene are also instantiated in memory by Unity and act like a kind of memory-mapped object/file in the Editor).
There are also ScriptableObjects that share a lot with gameobjects but are not "active" gameobjects and then are great to store data as they don't consume CPU and can be stored in assets.
What exactly do you want to do ?
I don't need the new GameObject. I just use it to "instantiate" $$anonymous$$onobehaviour Spawner$$anonymous$$2Single class.
What I exactly need is component like this on the picture
Usually, what I do for this kind of situation is to have 1 gameobject prefab for each spawner type. Just create an instance of 1 spawner in the scene, then drag&drop it in your Project/Asset to create a first prefab. Then, you can edit this prefab as you want. You can then select it and use "ctrl+D" to duplicate the file and create another spawner type that you can rename and edit as you want, and so on.
To have a list of those prefabs, you can have a gameobject+component that will contain a list of those gameobjects+component, just like you have with Spawner$$anonymous$$2. With the default inspector, you'll be able to add & remove elements and drag & drop the previously created spawner prefabs in the list's elements to reference them (try right click menu on the list's elements for additional options). You can also create a prefab of the spawnerlist Spawner$$anonymous$$2 and drag & drop prefabs into the List of the prefab (not an instance in scene, just reference prefab from a prefab). This is interesting because you can easily duplicate this list and only change a few elements. Doing this way, if you modify a spawner's values, it will then be changed in all the lists it's referenced from.
Last step is to reference the list's prefab from a public field of a "game manager" object in your scene so you can access it. Warning, any change made to the prefabs in memory will be written to disk during next save. It can be interesting but also dangerous. Instantiate the list from the prefab if you want an independent object/instance.
You can also use a custom inspector to have the kind of view you want, expect to spend some time developing this custom inspector though, that's not so simple. I think you have all the functionalities you want with the default prefab system. It will be faster to use it now and maybe develop a custom inspector later.
(you could also use ScriptableObjects but that's more complicated to implement)
Thank you. I found a nice piece of code that solves my problem http://forum.unity3d.com/threads/display-a-list-class-with-a-custom-editor-script.227847/