- Home /
Custom editor desperation: instance of custom class
I have the following custom class:
using UnityEngine;
using System.Collections;
public class test : MonoBehaviour {
public Vector3 var1 = new Vector3(1,2,3);
public string var2 = "ghhghahgh";
}
Said class has a properly working custom editor:
using UnityEngine;
using UnityEditor;
[CustomEditor (typeof(test))]
public class testeditor : Editor {
test varelement;
public override void OnInspectorGUI() {
varelement = (test)target;
varelement.var1 = EditorGUILayout.Vector3Field("Var 1", varelement.var1);
varelement.var2 = EditorGUILayout.TextField("Var 2", varelement.var2);
if(GUI.changed) {
EditorUtility.SetDirty(target);
}
}
}
Now I need to include a 'test' instance in another script:
using UnityEngine;
public class bigclass: MonoBehaviour {
public test mytest;
//several other components
}
THE RETARDED PROBLEM
No matter what I do, I can't get a custom editor to work for 'bigclass' since I receive two OnInspectorGUI nullreferenceexception
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(bigclass))]
public class bigclasseditor : Editor {
public override void OnInspectorGUI()
{
bigclass myclass = (bigclass)target;
//MYTEST IS -ALWAYS NULL- REGARDLESS OF HOW WELL IT WORKS AS A SINGLE COMPONENT
myclass.mytest.var1 = EditorGUILayout.Vector3Field("Var 1", myclass.mytest.var1);
//put here to understand how the inspector sees the component
DrawDefaultInspector();
}
}
As a matter of fact, the inspector shows it as an object, with 'none' value without the custom editor, so why on earth it's not initialized to its default values as it does when it's instantiated singularly?
I've even tried converting to stand alone classes, but doing such I can't build a custom inspector for them since I am unable to assign the 'target' to 'test' for iteration.
"CS0030: Cannot convert type `UnityEngine.Object' to `test'"
There must be something I'm missing to see here, but despite hours of searching and trying, I can't understand why the 'test' instance isn't instantiated by 'bigclass'. It makes no sense at all. I even tried the executeineditormode approach without the slightest change in result.
Hopefully there's someone able to help with this issue. Even refactoring the whole data structure led me to the same problem.
Forgive me for asking another stupid question, but are you ever assigning anything to 'mytest' in the editor? Unless you do, it will always remain null- there is nothing which magically assigns it, other than Unity's serialization- and anything which descends from $$anonymous$$onoBehaviour will be treated like a drag-and-drop box, not a dropdown. Why does the 'test' class have to be a $$anonymous$$onoBehaviour? You can just use a base class with the [System.Serializable] tag if you want it to show up in the inspector, and it seems you are just using it to store two variables- far, far less than the full functionality which a Component affords you.
In fact if you do that, I don't see why you need to use a custom editor at all...
There's two problems. When using a monobehaviour, I can type
'bigclass myclass = (bigclass)target;'
without errors, but then 'myclass' instance is null
If I use a base class, I can't type
'bigclass myclass = (bigclass)target;'
because I need an object for that, and the compiler tells me that I can't convert from object to 'test'.
I can't see a way out, since my objective is to have a custom editor for this.
Answer by syclamoth · Oct 27, 2011 at 10:35 AM
(I'm making this an answer, because it's rapidly becoming too large for the comments section)
Well, no- if you make the custom editor for the MonoBehaviour derived bigclass (which I don't like the non-capitalisation of, but let's sort out your real problem before getting into nitpicking), then target will be a 'bigclass' type object, which is all well and good. However, you say that the problem arises because of one of the members of bigclass, namely one of the type 'test' which never gets instantiated (which, frankly, doesn't surprise me, since nowhere in there do you manually instantiate it, and you're not assigning it in the editor because that would defeat the purpose).
What I'm saying is that while 'bigclass' must derive from MonoBehaviour for the custom editor to work, 'test' does not- the problem is that test is a reference type, not a value type! Nowhere do you create a new one, so obviously it will always return null. If test looked more like this-
public struct test{
public Vector3 var1 = new Vector3(1,2,3);
public string var2 = "ghhghahgh";
}
your specific problem would go away. Of course, Unity still can't serialise this, so won't save it between sessions. Otherwise, use
[System.Serializable]
public class test {
public Vector3 var1 = new Vector3(1,2,3);
public string var2 = "ghhghahgh";
}
which, by the way, you wouldn't need a custom editor to be able to see if you made it a public member of a MonoBehaviour.
What are you doing in the 'test' class which so requires it to derive from MonoBehaviour? I understand why the bigclass object needs to, I don't dispute that, but nothing you've said has explained to me why all its members have to as well.
Hah sorry for the capitalisation.
Anyways, thanks for taking the time of going through this heh.
Actually the only reason why I used a $$anonymous$$onoBehaviour for 'test' is that such declaration allowed me to
'bigclass myclass = (bigclass)target;'
in bigclasseditor.
As a matter of fact, if I could change 'test' into a generic class (can't opt for a struct since I need the serialization) AND I could access it from 'bigclasseditor' (which I can't figure out how), the problem would be solved.
Point being: I actually need an inspector for 'test' because it will eventually hold at least a dozen more properties that I need to represent differently through an inspector (for example, I will store two different Vector2 that I will show as a Rect in the custom inspector).
Ultimately, if I were able to:
1- derive from $$anonymous$$onoBehaviour and somewhat 'Reset' or 'Instantiate' the reference to an actual object (as if dragging test it into a gameobject).
or
2- use a custom class and correctly dereference it in the custom inspector,
I'd have reached my goal. Sadly, my attempts to 'instantiate' the 'test' in 'bigclass' or to 'cast' test from the target (in the case of 'test' as a generic class) have failed miserably.
You can just make a custom editor for bigclass, and then in that editor, modify the values in test. You don't nessecarily need a custom editor for both!
Or, let me put it this way. Will you ever attach a 'test' to a gameObejct as a component? If the answer is no, then you don't need it to be a monobehaviour.
Your answer
Follow this Question
Related Questions
Custom inspector, show string instead of component type 0 Answers
Simple text in inspector components? 2 Answers
Inspector button for custom class 1 Answer
Accessing components through a collision 0 Answers
Custom Editor problems 2 Answers