Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by SmooveB · Jun 28, 2012 at 05:17 AM · editorinspectorclasscustom

How do you make a custom inspector for a class or instance?

I have a class that looks like this:

 [Serializable]
 public class Encounter{
     public string[] encounterEnemy;
 }

I want custom inspector stuff that shows up when this class is part of other classes, arrays etc (in this case, I want the encounterEnemy to show up as a drop down list, but that is not really important).

I can make custom inspector GUI for variables found in the main body of scripts, but I can't seem to do anything with any other classes, even if they inherit from monobehavior.

Here is an example of something I am trying that does not work:

The script named TestScript

 using UnityEngine;
 using System.Collections;
 using System;
 
 
 public class TestClass : MonoBehaviour{
         public int testInt;
 }
 


The script named TestClassEditor

 using UnityEngine;
 using UnityEditor;
 using System.Collections;
 
 
 
 
 [CanEditMultipleObjects]
 [CustomEditor(typeof(TestClass))]//notice that this refers to the class declaration and not the main script
 public class TestClassEditor : Editor {
 
     SerializedObject testClass; 
     
     SerializedProperty testInt;
     
     string[] junk = {"things","stuff","whatever"};
     
     void OnEnable()
     {
             
         testClass = new SerializedObject(target);
 
         testInt = testClass.FindProperty("testInt");
 
     }
     
     public override void OnInspectorGUI () {
         testClass.Update();
         
         testInt.intValue = EditorGUILayout.Popup("Enemy",testInt.intValue,junk);
         
         testClass.ApplyModifiedProperties();
     }            
 
 }
     public class TestScript : MonoBehaviour {
     
         public TestClass testClassInst;
             
     }

Other posts (I have searched extensively) seem to suggest that doing this for instances of the class(not the class itself) but I have not been able to figure out how that might be done in an array or as part of another class.

Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image AlucardJay · Jun 28, 2012 at 07:30 PM 1
Share

I have no knowledge on this, but maybe there's something in this link that may help :

http://catlikecoding.com/unity/tutorials/star/

I could be entirely missing the point, but that tutorial was my intro to Custom Inspector/Editor.

avatar image SmooveB · Jun 29, 2012 at 12:32 AM 0
Share

This is the best Custom Inspector/Editor tutorial I was able to find. It got me to the point where I could even ask this question.

3 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Loius · Jun 28, 2012 at 09:11 PM

Is this what you're looking for, or did I misinterpret the question? (Maybe it's a C#-specific issue? Unityscript is so lazy by comparison but I don't trust my C#-ing for inspectors yet)

I don't know of a way to write an Inspector for an inner class, but I've been working around it for a while this way:

[SomeEncounters.js]

 class SomeEncounters extends MonoBehaviour {
   class Encounter {
     var monster : int;
     function InspectorGUI() {
       monster = EditorGUILayout.Popup( ... );   
     }
   }
   var encounter : Encounter;
 }

[SEEdit.js]

 @CustomEditor(SomeEncounters)
 class SEEdit extends Editor {
   function OnInspectorGUI() {
     super.OnInspectorGUI();
     target.encounter.InspectorGUI();
   }
 }


You'd still have to write the custom inspector for any class that uses the encounter (SomeEncounters in this case), but this is how I've been making class-specific inspectors for a while now.

You could have an array of Encounters, just have to set the size with an IntField and call the InspectorGUI on each element.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image SmooveB · Jun 28, 2012 at 11:56 PM 0
Share

Hey, I actually don't know what super is. Can your break it down for me? As for setting this stuff up in a function of the class, that is a great way to deal with this. Writing a custom inspector for every script that uses that class is no problem. I actually figured out how to write an inspector for an inner class. I will post the code shortly, but your solution is still probably superior because this thing is several levels deep (you will see when I post the code). Anyway, many thanks.

avatar image Loius · Jun 29, 2012 at 12:26 AM 1
Share

The equivalent in C# is "base" (I had to go look it up, heh). It's a reference to "this", but as the parent type. So the 'super' in that snippet refers to Editor, meaning it calls Editor.InspectorGUI - which draws the default inspector. It's usually convenient to draw the default inspector first, and if you get varibales showing up in the default inspector that you don't want, you can use @HideInInspector:

[file.cs]

 [HideInInspector]
 public bool x; // this won't show up in the default inspector, but your custom inspector is certainly free to use it
avatar image
2

Answer by SmooveB · Jun 29, 2012 at 12:16 AM

This is what I ultimately did to write an inspector for a class that was part of an array that was part of several other classes. If you don't want to search through the fairly ugly code, the takeaway is that you can use SerializedProperty Methods GetArrayelementAtIndex() and FindPropertyRelative() to and the property arraySize to drill down through Serialized classes and arrays in basically the same way you would in your regular code. Infact, you could use regular array methods if you are just setting things directly with target. Note that this is very ugly in the Inspector because I don't really understand formatting yet.

     [Serializable]
     public class Enemy{ //this is not the same as enemy in the editor script which is just a string
         public string name;
         public GameObject prefab;
         public int health;
         public int curHealth;
         public int damage;
         
         
         public void SetFromPrefab()
         {
             name = prefab.name;
             EnemyBaseStats enemyBaseStats = prefab.GetComponent<EnemyBaseStats>();
             health = enemyBaseStats.health;
             curHealth = enemyBaseStats.curHealth;
             damage = enemyBaseStats.damage;        
             
         }
 }
     
     [Serializable]
     public class Encounter{
         public string[] encounterEnemies;
     }
     
     [Serializable]
     public class Zone{
         public string name;
         public int encounterPercent;
         public Encounter[] zoneEncounters = new Encounter[0];       
     }
     
     
     [Serializable]
     public class PC{
         public string name;
         public GameObject PCPrefab;
         public Ability[] abilities;
         public int damage;
         public int health;
         public int maxHealth;    
     }
     
  
 
 
 public class Uni : MonoBehaviour {
     
     
     public Enemy[] preAllEnemies;
 
     public Zone[] preZones;
     }


Then the Editor

 [CustomEditor(typeof(Uni))]
 
 [CanEditMultipleObjects]
 
 public class DropDownMenu : Editor {
 
     private int index;
     private string[] preAllEnemiesString;
     private Uni uniEdNS;
     
     private SerializedObject uniSR;
     private SerializedProperty
             preZones;
     
     void OnEnable()
     {
         uniSR = new SerializedObject(target);
         preZones = uniSR.FindProperty("preZones");
         uniEdNS = (Uni)target;
         preAllEnemiesString = new string[uniEdNS.preAllEnemies.Length];
         
         for(int x = 0; x < uniEdNS.preAllEnemies.Length; x++)
         {
             preAllEnemiesString[x] = uniEdNS.preAllEnemies[x].prefab.name;
         }
     }
     
     public override void OnInspectorGUI () {
         
         uniSR.Update();
         
 
         for (int k = 0; k < preZones.arraySize; k++) //SerializedProperty has its own properties and methods for dealing with arrays: arraySize, GetArrayElementAtIndex() are used to drill down through my class to get to the strings
         {
             EditorGUILayout.LabelField("Zone " + k); //these are just labels to help organize what this looks like in the inspector window. It is really ugly right now because I don't yet understand formating
             
             SerializedProperty zone = preZones.GetArrayElementAtIndex(k);
             SerializedProperty encounters = zone.FindPropertyRelative("zoneEncounters");//I did not think this would work but it did. FindPropertyRelative uses the path of the SerializedProperty (in this case whichever zone is currently being delt with) and adds the argument to get a SerializedProperty one level down
             
             for (int l = 0; l < encounters.arraySize; l++)
             {
                 EditorGUILayout.LabelField("encounter " + l);
                 EditorGUILayout.BeginVertical();//more formatting
             
                 SerializedProperty encounter = encounters.GetArrayElementAtIndex(l);
                 SerializedProperty encounterEnemies =  encounter.FindPropertyRelative("encounterEnemies");
                 
                 for(int m = 0; m < encounterEnemies.arraySize; m++)
                 {
                     SerializedProperty enemy = encounterEnemies.GetArrayElementAtIndex(m);
                     
                     for(int j = 0; j < preAllEnemiesString.Length; j++)//the way I have it set up, the value that is actualy stored is the string. But popups use and return ints. This checks the stored string and sets the popup accordingly
                     {
                         
                         if (enemy.stringValue == preAllEnemiesString[j]) 
                         {
                             index = j;
                             
                         }
                         
                     }
                     
                     
                         index = EditorGUILayout.Popup("Enemy",index,preAllEnemiesString);
                         enemy.stringValue = preAllEnemiesString[index];// this uses the value I get from the popup as an index to get the correct string. I can move elements of preAllEnemies around and no harm will be done to the enemy values, but if a value is not found in the preAllEnemies list, the enemy will revert to 0.
                     
                     
                     
                 }
                 
 
 
                 EditorGUILayout.EndVertical();
                     
             }
             
         }
         
         uniSR.ApplyModifiedProperties();
         DrawDefaultInspector ();
     }
     }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
1

Answer by Eric5h5 · Jun 28, 2012 at 05:30 AM

You can't yet; wait for Unity 4.

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image SmooveB · Jun 28, 2012 at 05:51 AM 0
Share

That would explain why I have spent the last 2 days failing at this task. Do you have any other suggestions about alternative ways to accomplish my real goal of having drop down menus in my string array (inside an instance of a class)?

avatar image Eric5h5 · Jun 28, 2012 at 06:02 AM 0
Share

Can you use an enum ins$$anonymous$$d of strings?

avatar image SmooveB · Jun 28, 2012 at 07:22 PM 0
Share

Hmm. Not unless I can somehow create the enum from a list of strings. The situation is this: I have monsters for an old school jrpg. They each have a prefab that has their stats template and their art etc (I have also considered just have them be objects and skipping the prefabs) These prefabs go into a Dictionary with a string key (I could make it an array). There could be 500+ monsters by the end of the thing, so maintaining a separate enum is asking for trouble.

Each zone has 5 to 10 pre set encounters. One aspect of each encounter is the enemies in that encounter. I wanted a drop down list to make it easy to select enemies for each position in the encounter. Obviously, enums would work fine for this, I would just have to convert to string when I went to set up for an actual encounter. The problem is just that creating a separate list of enums is out of the question and I don't see a way to mix an enum into the enemy Dictionary (or array) or to create an enum list from that Dictionary. Thoughts?

avatar image Paulius-Liekis · Oct 20, 2015 at 12:11 PM 0
Share

Can you do this in Unity 4?

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

8 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Inspector button for custom class 1 Answer

Get if inspector field labels are on separate line 1 Answer

Can i extend or customise editor for all MonoBehaviours? 3 Answers

How can I create a list of preset class/objects to be used in the editor 1 Answer

Call inspector on custom window editor 4 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges