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]Using Popup Property Drawer for Enumerations with special symbols

Discussion in 'Scripting' started by IsGreen, Aug 27, 2014.

  1. IsGreen

    IsGreen

    Joined:
    Jan 17, 2014
    Posts:
    206
    I'm looking for a way to create enumerations with special symbols. And the easiest way I've found to create a list or Popup from Inspector has been: Property Drawers in Unity 4.

    But, this code:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Example : MonoBehaviour {
    5.  
    6.     [Popup ("Warrior", "Mage", "Archer", "Ninja")]
    7.     public string @class = "Warrior";
    8.  
    9. }
    It throws the following errors:

    I have installed 4.5.1f3 Unity version. Any solution?

    ____________________________________________________________
    ____________________________________________________________

    [SOLVED]

    Enumeration class, type to define enumerations from items field:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Enumeration{
    4.  
    5.     public static readonly string[] items;
    6.  
    7. }
    8.  
    9. //Example 1
    10. public class CameraResolutions : Enumeration{
    11.  
    12.     public static readonly new string[] items = new string[]{ "Free Aspect","5:4","4:3","3:2","16:10","16:9" };
    13.  
    14. }
    15.  
    16. //Example 2
    17. public class Fraction4 : Enumeration{
    18.  
    19.     public static readonly new string[] items = new string[]{ "1\\4","2\\4","3\\4","4\\4" };
    20.  
    21. }
    PropertyAttribute class, with class type and string params constructor:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Enum : PropertyAttribute{
    4.  
    5.     public readonly string[] items;
    6.     public int selected = 0;
    7.  
    8.     public Enum(System.Type type){
    9.  
    10.         if (type.IsSubclassOf(typeof(Enumeration)))
    11.         {
    12.             System.Reflection.FieldInfo fieldInfo = type.GetField("items");
    13.             this.items = (string[])fieldInfo.GetValue (null);
    14.  
    15.         } else {
    16.  
    17.             this.items = new string[]{"Assign Enumeration Type"};
    18.  
    19.         }  
    20.  
    21.     }
    22.  
    23.     public Enum(params string[] enumerations){ this.items = enumerations; }
    24.  
    25. }
    PropertyDrawer class, in Editor folder, to create popup list:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. [CustomPropertyDrawer (typeof (Enum))]
    5. public class EnumDrawer : PropertyDrawer {
    6.  
    7.     Enum enumeration{ get{ return (Enum)attribute; } }
    8.  
    9.     bool Start = true;
    10.  
    11.     public override void OnGUI (Rect position, SerializedProperty prop, GUIContent label) {
    12.      
    13.         if(Start){
    14.          
    15.             Start = false;
    16.             for(int i=0;i<enumeration.items.Length;i++){
    17.              
    18.                 if(enumeration.items[i].Equals(prop.stringValue)){
    19.                  
    20.                     enumeration.selected = i;
    21.                     break;
    22.                  
    23.                 }
    24.              
    25.             }
    26.          
    27.         }
    28.      
    29.         enumeration.selected = EditorGUI.Popup(EditorGUI.PrefixLabel(position, label),enumeration.selected,enumeration.items);
    30.         prop.stringValue = enumeration.items[enumeration.selected];
    31.      
    32.     }
    33.      
    34. }
    Script Test:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class EnumerationTest : MonoBehaviour {
    4.  
    5.     [Enum("Free Aspect","5:4","4:3","3:2","16:10","16:9")]
    6.     public string cameraResolution = "3:2";
    7.  
    8.     [Enum("1\\4","2\\4","3\\4","4\\4")]
    9.     public string fraction;
    10.  
    11.     [Enum(typeof(CameraResolutions))]
    12.     public string camResolution;
    13.  
    14.     [Enum(typeof(Fraction4))]
    15.     public string frac="4\\4";
    16.  
    17.  
    18.     void Start(){
    19.  
    20.         Debug.Log(cameraResolution);
    21.         Debug.Log(fraction);
    22.         Debug.Log(camResolution);
    23.         Debug.Log(frac);
    24.  
    25.     }
    26.  
    27. }
     
    Last edited: Aug 28, 2014
  2. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Popup is not a built-in attribute
    you have to script it yourself
    That page tells you how to create a regexAttribute, now go make a popupAttribute
     
  3. IsGreen

    IsGreen

    Joined:
    Jan 17, 2014
    Posts:
    206
    Ok. I tested this code.

    This is Enumeration class, PropertyAttribute derived:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Enumeration : PropertyAttribute {
    4.    
    5.     public readonly string[] items;
    6.     public int selected = 0;
    7.    
    8.     public Enumeration(string[] enumerations){ this.items = enumerations; }
    9.  
    10. }
    This is EnumerationDrawer class, PropertyDrawer derived:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. [CustomPropertyDrawer (typeof (Enumeration))]
    5. public class EnumerationDrawer : PropertyDrawer {
    6.  
    7.     Enumeration enumeration{ get{ return (Enumeration)attribute; } }
    8.  
    9.     public override void OnGUI (Rect position, SerializedProperty prop, GUIContent label) {
    10.  
    11.         enumeration.selected = EditorGUI.Popup(EditorGUI.PrefixLabel(position, label),enumeration.selected,enumeration.items);
    12.  
    13.     }
    14.  
    15. }
    And this is EnumerationTest:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class EnumerationTest : MonoBehaviour {
    4.  
    5.     [Enumeration(new string[]{ "Free Aspect","5:4","4:3","3:2","16:10","16:9" })]
    6.     public string cameraResolution;
    7.  
    8.     [Enumeration(new string[]{ "1/4","2/4","3/4","4/4" })]
    9.     public string fraction;
    10.  
    11.     void Start(){
    12.  
    13.         Debug.Log(cameraResolution);
    14.         Debug.Log(fraction);
    15.  
    16.     }
    17.  
    18. }
    Result this:



    Questions:

    1) How to write symbol /. The image show two panels or menus.
    2) Debug.log considers the string variables as objects.
    3) In example: Property Drawers in Unity 4, Popup attribute use indefined number of arguments, using comma-separated string.
     
  4. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    1 Maybe use \\ for a slash, dont think there is an escape for a forward slash

    2 Everything from Debug.log is an object. Your variables are strings

    3 Change line 8 your constructor to use params like (can't test atm):
    Code (CSharp):
    1.     public Enumeration(params string[] enumerations){ this.items = enumerations; }
     
  5. IsGreen

    IsGreen

    Joined:
    Jan 17, 2014
    Posts:
    206
    Thanks for advice.

    I have changed / symbol by \\, and added 'params' to constructor.

    To change string value, I returned to study the example, and I have seen the need to access the prop (SerializedProperty value) in PropertyDrawer OnGUI function.