Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

[SOLVED] In Unity, public variables can be seen in the Inspector, right? See inside for details.

Discussion in 'Scripting' started by Deleted User, Sep 9, 2014.

  1. Deleted User

    Deleted User

    Guest

    I want to add public variables in the Inspector if certain fields are chosen. For example:

    public bool canWalk;

    if (canWalk == true){
    Add public float walkSpeed to the Inspector
    }

    How can I do this?

    EDIT: Solved. Bought HeavyDuty Inspector to make it simpler, although there are a few Inspector assets in the asset store.
     
    Last edited by a moderator: Oct 24, 2014
  2. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    I've found editor tutorials hard to find. So I'm writing out the whole thing so you can see how I'd accomplish this. We pretty much override the default inspector behaviour and replace it with how we want it to act.

    This doesn't mean the walkSpeed float is hidden from everyone. Putting the inspector in debug mode will show all public variables and not run the editor script!
    Code (csharp):
    1. using UnityEngine;
    2.  
    3. public class WalkClass : MonoBehaviour
    4. {
    5.   public bool canWalk;
    6.   public float walkSpeed;
    7. }
    Code (csharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. [CustomEditor(typeof(WalkClass))]
    5. public class WalkClassEditor : Editor
    6. {
    7.   private SerializedProperty canWalkProperty;
    8.   private SerializedProperty walkSpeedProperty;
    9.  
    10.   void OnEnable()
    11.   {
    12.     canWalkProperty = serializedObject.FindProperty("canWalk");
    13.     walkSpeedProperty = serializedObject.FindProperty("walkSpeed");
    14.   }
    15.  
    16.   public override void OnInspectorGUI()
    17.   {
    18.     serializedObject.Update();
    19.     EditorGUILayout.BeginVertical();
    20.     EditorGUILayout.PropertyField(canWalkProperty);
    21.     // The magic happens right here!
    22.     if (canWalkProperty.boolValue)
    23.       EditorGUILayout.PropertyField(walkSpeedProperty);
    24.     EditorGUILayout.EndVertical();
    25.     serializedObject.ApplyModifiedProperties();
    26.   }
    27. }
     
    Last edited: Sep 9, 2014
  3. Deleted User

    Deleted User

    Guest

    That's really cool.
    What about game performance or size? Will it be impacted by this?
     
  4. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    Editor scripts do not get put in the build and only run in the Unity Editor. So no effect on a build to device!

    IMPORTANT! I forgot to add that you need to make a sub-folder called "Editor" and put the UnityEditor scripts in there. The parent folder doesn't matter. I have dozens of Editor folders in my projects. Otherwise the script gets included in your build and will fail if you use anything from the UnityEditor namespace.
     
    Last edited: Sep 9, 2014
  5. Deleted User

    Deleted User

    Guest

    I tried implementing it and I'm getting errors.
    Basically, I have a canSpawn bool and if checked, it should show an array of game object fields in the editor.
    However, when checked, the name of the array displays, but not the editable fields themselves.
    Does that make sense?

    Here's my first script:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class EnemySpawnScript : MonoBehaviour
    5. {
    6.  
    7.         public bool hasSpawned;
    8.         public bool canSpawn;
    9.         public GameObject[] enemies = new GameObject[1];
    10.    
    11.         void Start ()
    12.         {
    13.                 if (enemies != null) {
    14.                         var x = Instantiate (enemies [0], transform.position, Quaternion.identity) as Transform;
    15.                 }
    16.         }
    17.  
    18.         void Update ()
    19.         {
    20.                 if (hasSpawned == false) {
    21.                         if (renderer.IsVisibleFrom (Camera.main)) {
    22.                                 hasSpawned = true;
    23.                         }
    24.                 } else if (renderer.IsVisibleFrom (Camera.main)) {
    25.                         Destroy (gameObject);
    26.                 }
    27.         }
    28. }
    Editor script:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. [CustomEditor(typeof(EnemySpawnScript))]
    5. public class EnemySpawnEditor : Editor
    6. {
    7.  
    8.         private SerializedProperty canSpawnProperty;
    9.         private SerializedProperty enemiesProperty;
    10.    
    11.         void OnEnable ()
    12.         {
    13.                 canSpawnProperty = serializedObject.FindProperty ("canSpawn");
    14.                 enemiesProperty = serializedObject.FindProperty ("enemies");
    15.         }
    16.    
    17.         public override void OnInspectorGUI ()
    18.         {
    19.                 serializedObject.Update ();
    20.                 EditorGUILayout.BeginVertical ();
    21.                 EditorGUILayout.PropertyField (canSpawnProperty);
    22.                 if (canSpawnProperty.boolValue)
    23.                         EditorGUILayout.PropertyField (enemiesProperty);
    24.                 EditorGUILayout.EndVertical ();
    25.                 serializedObject.ApplyModifiedProperties ();
    26.         }
    27. }
     
  6. Deleted User

    Deleted User

    Guest

  7. Hunter_W

    Hunter_W

    Joined:
    May 5, 2014
    Posts:
    57
  8. Deleted User

    Deleted User

    Guest

    Thanks, that looks good.

    I added those attributes but I get errors:
    "The type or namespace name `Selector' could not be found. Are you missing a using directive or an assembly reference?"
    I get those errors for all of them.
     
    Last edited by a moderator: Sep 10, 2014
  9. Hunter_W

    Hunter_W

    Joined:
    May 5, 2014
    Posts:
    57
    You are right. Obviously, it works, but the site does not provide the correct way in doing so. I will continue to look for another solution. I have checked the API and have yet to see a compatible attribute.
     
  10. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,716
    And if you want an easier way, there's always "Advanced Inspector" in my signature... Which you can do all that without ever writing a Custom Editior.

    Here's an example of hiding a variable because an another variable is null, or it doesn't have a Light component;

    Code (CSharp):
    1. public class MyBehaviour : MonoBehaviour
    2. {
    3.     [Inspect]
    4.     public GameObject go;
    5.  
    6.     [Inspect("HasLight")]
    7.     public bool activateLight = false;
    8.  
    9.     private bool HasLight()
    10.     {
    11.         return go != null && go.GetComponent<Light>() != null;
    12.     }
    13. }
    14.  
     
  11. billykater

    billykater

    Joined:
    Mar 12, 2011
    Posts:
    327
    As LighStriker already demonstrated this can be done with CustomPropertyDrawers. This way you won't need to write a custom editor for each script using this behaviour.
    HideIfNotSet.cs
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class HideIfNotSetAttribute : PropertyAttribute
    4. {
    5.     public string BoolProperty { get; private set; }
    6.    
    7.     public HideIfNotSetAttribute(string boolProperty)
    8.     {
    9.         BoolProperty = boolProperty;
    10.     }
    11. }
    Editor\HideIfNotSetDrawer.cs
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. [CustomPropertyDrawer(typeof(HideIfNotSetAttribute))]
    5. public class HideIfNotSetDrawer : PropertyDrawer
    6. {
    7.     public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    8.     {
    9.         var hideAttribute = attribute as HideIfNotSetAttribute;
    10.         var boolProperty = property.serializedObject.FindProperty(hideAttribute.BoolProperty);
    11.         if(boolProperty != null && !boolProperty.boolValue)
    12.         {
    13.             return 0;
    14.         }
    15.         else
    16.             return base.GetPropertyHeight(property, label);
    17.     }
    18.    
    19.     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    20.     {
    21.         var hideAttribute = attribute as HideIfNotSetAttribute;
    22.         var boolProperty = property.serializedObject.FindProperty(hideAttribute.BoolProperty);
    23.         if(boolProperty != null)
    24.         {
    25.             if(boolProperty.propertyType == SerializedPropertyType.Boolean)
    26.             {
    27.                 if(boolProperty.boolValue)
    28.                     EditorGUI.PropertyField(position, property, label, true);
    29.             }
    30.             else
    31.             {
    32.                 EditorGUI.HelpBox(position, string.Format("Property {0} is not boolean", hideAttribute.BoolProperty),MessageType.Error);
    33.             }
    34.         }
    35.         else
    36.         {
    37.             EditorGUI.HelpBox(position, string.Format("Couldn't find property {0}", hideAttribute.BoolProperty), MessageType.Error);
    38.         }
    39.     }
    40. }
    41.  
    And a test case
    Code (CSharp):
    1. public bool Show;
    2.    
    3. [HideIfNotSet("Show")]
    4. public string Path;
    Whenever Show is true, Path will be shown.

    If you want more advanced behaviour LightStrikers Asset sounds nice.
     
  12. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,716
    Well, I'm not using CustomPropertyDrawers because of some of their limitations, like they cannot use GUILayout/EditorGUILayout, and I think you can only have one flagging an item at a time? However, for lot of things they work just fine.
     
  13. Deleted User

    Deleted User

    Guest

    @LightStriker, I saw your asset along with some others but I don't have money. :p