- Home /
CustomEditor : DrawDefaultInspector for Class
Heya, I am to making a CustomEditor for one of my scipts.
I have a enum in my script, and it is getting nicely displayed in the inspector. What I want is the inspector to show different classes based on the enum.
For example: I choose the enum: spawnEnemy --> want to show the SpawnEnemyScript in the inspector. or I choose the enum: wait --> want to show the WaitXSecondsScript in the inspector.
I have no problems checking which enum there currently is selected. My problem is I don't want to make a custom view for all the different scripts that can be choosed.
I am looking for a function like DrawDefaultInspector(), just for another script than the CustomEditor for the script I am currently showing.
I'm not exactly sure what you're trying to achieve here. It seems like you are trying to create a script which then controls what other scripts run on your Game Object via an enum - am I correct in understanding this?
Glad to see I was understanding. This actually kind of breaks Unity's convention of having a different behaviour per script. What you're doing is creating a script, which would have to be a $$anonymous$$onoBehaviour and thus exist at run-time, be strictly an Editor object. Do you want to have all of these classes be behaviours of this game object and you're just switching, or do you only want one of these on there at a time and switching the enum value in your inspector would remove the old behaviour and replace it with a new one?
hmm.. on the different classes that I want to switch through, aren't $$anonymous$$onoBehaviour. I have a controller which is (the one containing the enum). But I want it to use different classes depending on an enum. And I want the class for the given enum shown in the Inspector(so I can change values, like spawnposition and such).
All my ActionScripts are extending from an BaseAction
I got:
LevelScript - extends $$anonymous$$onoBehavior and contains the Enum LevelScript got a BaseAction (as of now it only got 1 action) The BaseAction should then be initalized with either SpawnEnemyScript if "spawn enemy" is choosen in the enum, and WaitXSecScript, if the enum is "wait".
The BaseAction is NOT extending the $$anonymous$$onoBehavior, and so is non of the action scripts.
The Inspector only shows the BaseAction attributes, even if I have initalized it with SpawnEnemyScript/WaitXSecScript. And not the "happend-to-be" attritbutes on the other scripts.
I tried to create an @CustomEditor(LevelScript) class LevelScriptEditor { ... } where i then could control when and what to show, and it workes somewhat (I use this class to initalize the Scripts extending the BaseAction)
But I can't get it to show for example the DrawDefaultInspector() for the SpawnEnemyScript.
Answer by equalsequals · Aug 22, 2011 at 04:06 PM
I think I get what you're asking, but I'm still left asking "why?":
Inspectors by default only draw for MonoBehaviour derivatives, because only a MonoBehaviour can be attached as a Component to a GameObject.
What you're doing here is actually really going against Unity's grain and you're definitely making life harder for yourself.
The fact that you are calling a class "BaseAction" leads me to believe that it is the foundation class for a number of various actions that will be performed. In Unity, an "action" could probably be used synonymously with "behaviour" - which is why the whole MonoBehaviour class structure pretty much single-handedly drives Unity's API. It just seems to me like you are needlessly reinventing the wheel on this, is all.
With that said - only MonoBehaviours can be shown in the Inspector, but you can use the Editor API to script out custom editors for each one of these classes.
If you were to stick with this route though, here's probably the simplest way to do it:
1) LevelScript the MonoBehaviour has a property called action, which is a BaseAction. (The BaseAction class must be a SerializableAttribute)
2) Each additional action must extend BaseAction.
3) Use your custom inspector to set the value of the target LevelScript's action to the class corresponding to the enum, remember to destroy old references.
4) Depending on the action that is selected, you can draw inspector fields to edit it's properties. You can do this manually in a case switch because you will know what all the important properties are - or maybe use something like System.Reflection to traverse the class's properties and spit out fields.
It's a lot of work, which is why I suggest re-evaluating your approach to take advantage of Unity's power.
[Edit] The way I typically handle this Level Manager:
I will generally create an empty GameObject and name it "Managers" and I will attach various MonoBehaviour classes to this GameObject. (ie a class called LevelManager)
Then, any simple actions that are clearly defined will be attached to this same GameObject, or other GameObjects parented to the "Managers" (it depends on how many behaviours it needs) For instance I'll have one for spawning enemies, pickups, etc. which has reference to the objects that need to be spawned and they will contain the encapsulated logic for spawning them.
The LevelManager will have a reference to all of these other managers, so all you have to do is communicate with the level manager to update data and get things happening.
It makes for very small management classes that only serve one purpose and are very maleable.
Hope that helps.
==
Because not everything really is a gameobject, LevelScript shouldn't really extend $$anonymous$$onoBehaviour, because... well it is not a gameojbect, it is a class containing data about how a level should be executed, when and where what should happen. I would just had liked to use the inspector to create my levels.
To attach everything to gameobjects feels so... static. And furthermore an enduser gamer should never see a gameobject which contains the LevelScript.
That was my idea about the levelScript.
The player/end user won't see that GameObject as it isn't being rendered. GameObjects are simply containers that do nothing on their own but bundled with Components ($$anonymous$$onoBehaviour) drive the entire engine. I do all of my "Level $$anonymous$$anagers" this way - it is very extensible and extremely powerful. It is something that takes some getting used to, but once you are used to it, it really just makes sense.
In any case, I provided a sort of overview about how you'd get non-$$anonymous$$onoBehaviour objects drawing in your Inspector. Give it a shot if you're still looking to do it that way. Cheers!
"I do all of my "Level $$anonymous$$anagers" this way" huh? You create a game-object which got levelscript on it, then one gameobject for each BaseAction(SpawnEnemyScript/WaitXSecScript/..), and then associate those gameobjects(or scripts if nothing else) with the levelScript?
Can you explain this a bit more? $$anonymous$$aybe a link about best-practices and ideas behind.
@equalsequals Not just saying it for you ;) saying it because he's new and might simply not know. And it's indeed nice to be able to index answers.
Your answer
Follow this Question
Related Questions
Inspector Titlebar for class derived from Object 1 Answer
Inspector: custom property with custom type use default editor 3 Answers
Draw specific Object Inspector into Rect 1 Answer
How can a class inherit from another that is modified by editor 1 Answer
How should I serialize data that is also editable in the Inspector? 2 Answers