- Home /
Custom Inspector - How to add functionality?
Hello community,
I apologize in advance for not always using proper terms.
For the last 2 days I have been learning about how to modify the UI of the Inspector in Unity. I am quite happy with the result I have achieved so far. Today, I finished the basic structure and wanted to implement functionality. So far, when the user makes adjustments to something within the Inspector - those changes only affect the inspector and nothing else.
Basic Setup : I want to make my work easier. Instead of modifying tons of values each time I create a new "enemy" ,"player" or "npc" object - i just want to use my custom inspector. Here is some of the code I used :
 using UnityEditor;
 using System.Collections;
 using UnityEngine;
 
 [CustomEditor(typeof(HealthScript))]
 public class ControlInterface : Editor {
 
 //    ---------------------- START VARIABLES -----------------------------------    //
     SerializedObject serObj;   // i have no idea what that is 
     
     private bool isActiveOnCharacter = true;
     private bool useHealthTex =false;
     private bool monoHealthBar = true;
     private bool canRegenHealth = false;
     private bool canAttack = false;
 
     
     private string tagForObject="";
     private string tagForEnemy ="";
     
     private int characterTypeIndex;
     private string[] characterTypeOptions = new string[4] {"not Defined", "Player","Mob (hostile)","NPC (neutral)"};
     private string characterName="";
     
     SerializedProperty myMaxHealth; // again not much of an idea how that works
     private float myCurHealth = 0f;
 
     private float regenRate = 0f;
     private string[] RegenRateSamples = new string[4] {"slow","normal","fast","custom" };
     private int regenIndex =0;
     
     public Color green;
     
     public Transform myEnemy;
     private float baseDamage;
     private float hitChance;
     private float coolDown;
 //    ---------------------- End VARIABLES -------------------------------------    //
     
     public void OnEnable(){            // got the idea for the following 2 code lines from an existing unity script ( antialiasing)
 
         serObj = new SerializedObject(target);    
         
         myMaxHealth = serObj.FindProperty("myMaxHealth");
         
     }
     
     public override void OnInspectorGUI() {
         
         EditorGUIUtility.LookLikeInspector();
     
         isActiveOnCharacter = EditorGUILayout.Foldout(isActiveOnCharacter,"Character Setup:");
         
         EditorGUILayout.Separator();        
         
         if(isActiveOnCharacter){    
         
             characterTypeIndex = EditorGUILayout.Popup("Character Type: ",characterTypeIndex, characterTypeOptions);
         
             switch(characterTypeIndex){
             
             //    NOTHING CHOSEN
             case 0:
                 
                 //    THis function resets some of the specific values previously entered
                 //    and moreover is the default setting of "Character Type: ".
                 NotSpecified();
                 
                 break;
             
         
             
             //    PLAYER CHOSEN
             case 1:
                 
                 //    This function allows specifications about the Player object
                 //    and contains several functions that are being shared by the
                 //    different object types. 
                 SpecifiedPlayerObject();
                 
                 break;
                             
 
             //    MOB CHOSEN
             case 2:
                 
                 //    This function allows specifications about the Mob object
                 //    and contains several functions that are being shared by the
                 //    different object types.
                 SpecifiedMobObject();
                 
                 break;
             
             //    NPC CHOSEN
             case 3:
                 
                 //    This function allows specifications about the NPC object
                 //    and contains several functions that are being shared by the
                 //    different object types.                
                 SpecifiedNPCObject();
                 
                 break;
             //    Catch loopholes    
             default:
                 
                 //    Throw out a LogWarning - this message should never appear
                 //    if it does scream at developer!
                 Debug.LogWarning("Something went wrong ...!");
                 
                 break;
             }
         }    
     }
     
     
 //    ----------------------------Chosen Character------------------------------    //
     
     private void NotSpecified(){
         
         EditorGUILayout.BeginHorizontal("Button");
         
             EditorGUILayout.LabelField( "Please specify character type!");
         
         EditorGUILayout.EndHorizontal();
         //    ---------------Reset some Variables---------------    //         
         
         tagForObject="";
                 
         myMaxHealth = 0;
         
         myCurHealth = 0;
         
         regenIndex  = 0;
         
         regenRate   = 0;
         
         tagForEnemy ="";
         
         //    ---------------Reset some Variables---------------    //
     }
     
     private void SpecifiedPlayerObject(){
         
         EditorGUILayout.BeginVertical();
         
         SetupHealth ();
         
         GUILayout.Box("", new GUILayoutOption[]{GUILayout.ExpandWidth(true), GUILayout.Height(1)});
         
         PlayerOnlyHealthBarDisplay();
     
         GUILayout.Box("", new GUILayoutOption[]{GUILayout.ExpandWidth(true), GUILayout.Height(3)});
     
         SetupBasicAttack();
         
         EditorGUILayout.EndVertical();
         
     }
I have been trying to understand the basic principals using the Image Effect scripts from Unity. and in there it appeared as if they would simply say - every variable in my editor class is of type SerializedProperty and i would just assign the value inputed via
SerializedObject serObj;
some variable in my editor class =serObj.FindProperty("some variable I have in my "true" class);
i don't think that would work quite as I would want it to work.
Example :
I created a variable myMaxHealth in the Editor Class. (assume it was an int) . Then somewhere in the inspector I am storing a value to this variable :
 myMaxHealth = EditorGUILayout.IntSlider(....);
I would like to have this value been the new value of my true myMaxHealth variable in the real HealthScript class (not the editor).
Can you help me ? . I really tried finding a solution, but I am struggling. I know, I am quite far off track with my solutions... - at least I think I am .
Thank you,
Daniel
Answer by vbbartlett · Feb 13, 2013 at 08:31 PM
Basics: target is the instance of the class that the editor is displaying.
Thus if you have
 HealthScript hs = (HealthScript)target;
 
then if you actually want the gui controls to directly effect the instance you would do something like
 hs.m_maxHealth = EditorGuiLayout.IntSlider(hs.m_maxHealth,...)
  
This sets the slider to the value of the instance and then when it changes applies that change back to the instance.
I have a very simillar question, and I always end up with NullReferenceException when I'm trying to get access to a list from target in editor
this one is equal to HealthScript:
 public class EventScript : $$anonymous$$onoBehaviour {
 
     public List<Action> actionList;
 
     public class Action
     {
         float time;
         FieldInfo[] fieldInfos;
         object[] fieldValues;
 
         public Action(float time, FieldInfo[] fieldInfos, string eventName)
         {
             this.time = time;
             this.fieldInfos = fieldInfos;
             this.fieldValues = new object[3];
         }
     }
 
     void Awake()
     {
         actionList = new List<Action> ();
         actionList.Add(new Action(5.56f, new FieldInfo[3], "name"));
         actionList.Add(new Action(5.56f, new FieldInfo[3], "name"));
         actionList.Add(new Action(5.56f, new FieldInfo[3], "name"));
     }
 
     // Use this for initialization
     void CreateEvent()
     {
         // Call constructor of Event via reflection
     }
 }
and here I,m trying to get access to fields:
         [CustomEditor(typeof(EventScript))]
         public class EventEditor : Editor {
         
             private EventScript the_script;
             public List<EventScript.Action> actions;
         
             void OnEnable()
             {
                 the_script = (EventScript)target;
                 // How to get access to List<Action> "events" from currently editing instance's of EventScript?
                 for(int i = 0; i<the_script.actionList.Count; i++)
                 {
                     Debug.Log("WOW");
                 }
             }
         
             public override void OnInspectorGUI()
             {
         
             }
         }
 
 
this causes error: NullReferenceException: Object reference not set to an instance of an object EventEditor.OnEnable () (at Assets/Editor/EventEditor.cs:16)
Unholy crap, I've found the problem! This works pretty fine in play mode!
Your answer
 
 
             Follow this Question
Related Questions
Public Scene Variables not appearing in the inspector 2 Answers
Unity Editor - Class variable value contrain 4 Answers
ReImport in c# of GameObjects only for Scene Objects, not assets? 1 Answer
Parent Class variables in Child Class's Inspector (C#) 0 Answers
Editor Script, Index Out of Range Exception after Play 1 Answer
 koobas.hobune.stream
koobas.hobune.stream 
                       
               
 
			 
                