Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
4
Question by Jiraiyah · Mar 09, 2013 at 03:23 PM · unity4propertydrawer

property drawer for enum + two other attributes

hi everyone, i have a class like this :

    using UnityEngine;
     using System;
     [System.Serializable]
     public class ScaledCurve
     {   
         public float Speed = 1;
         public Animation Animation;
         //public int FPS;
         public AnimationFPS FPS;
     
     }
     public enum  AnimationFPS { WEB = 15, Film = 24, PAL = 25, NTSC = 30, HDTV = 60, UHDTV = 120 }

now, i'm writing a drawer for it in unity 4 but : i can't make the enum show properly, and, i want the float slider show in one line then go to next vertical line and show the other stuff there, here is what i tried till now : using UnityEngine; using UnityEditor; using System;

 [CustomPropertyDrawer(typeof(ScaledCurve))]
 public class ScaledCurveDrawer : PropertyDrawer
 {
     const int curveWidth = 50;
     const float min = 0.1f;
     const float max = 10;
     const int fmin = 15;
     const int fmax = 120;
     const int animFieldWidth = 120;
     private const int FPSWidth = 70;
     private float wid;
     public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
     {
         SerializedProperty speed = prop.FindPropertyRelative("Speed");
         SerializedProperty anim = prop.FindPropertyRelative("Animation");
         SerializedProperty fps = prop.FindPropertyRelative("fps");
         EditorGUILayout.BeginVertical();
         EditorGUILayout.BeginHorizontal();
         // Draw Speed
             
             EditorGUI.Slider(
                 new Rect(pos.x, pos.y, pos.width, pos.height),
                 speed, min, max, label);
             // Draw FPS
         EditorGUILayout.EndHorizontal();
         EditorGUILayout.BeginHorizontal();
         //EditorGUI.PropertyField(
         //    new Rect(pos.width - (animFieldWidth) - FPSWidth, pos.y, FPSWidth, pos.height), fps);
         EditorGUI.Popup(
            new Rect(3, 3, pos.width - 6, 15),
            "FPS",3,
            fps.enumNames);
 
         EditorGUI.indentLevel++;
         // Draw Animation Field
         EditorGUI.indentLevel = 0;
         EditorGUI.PropertyField(
             new Rect(pos.width - animFieldWidth, pos.y, animFieldWidth, pos.height),
             anim, GUIContent.none);
         EditorGUILayout.EndHorizontal();
         EditorGUILayout.EndVertical();
     }
 }

now, the problem is like this : 1- begin horizontal and vertical gives error 2- the editorGUI.propertyField is not what i'm looking for, EditorGUI.EnumPopup is looking for an enum and i can't use the serialized fps variable that i'm defining

can anyone help on these? also i saw this page : [blog post about property drawer] [1]: http://blogs.unity3d.com/2012/09/07/property-drawers-in-unity-4/

would be nice if someone can write those [Popup] and [Angle] functions and share with us

thanks for help

Comment
Add comment
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

2 Replies

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

Answer by Jiraiyah · Mar 09, 2013 at 07:46 PM

heh i just found the solution, anyway, i put it together just in case anyone has some problem like this : 1- first you need a public enum as i had in the serializable class :

 using UnityEngine;
 using System;
 [System.Serializable]
 public class AnimationClass
 {   
     public float Speed = 1;
     public Animation Animation;
     //public int FPS;
     public AnimationFPS FPS;
 
 }
 
 public enum AnimationFPS { WEB = 15, Film = 24, PAL = 25, NTSC = 30, HDTV = 60, UHDTV = 120 }

2- now you need to address it in the drawer class like this :

 using UnityEngine;
 using UnityEditor;
 using System;
 
 [CustomPropertyDrawer(typeof(AnimationClass))]
 public class AnimationClassDrawer : PropertyDrawer
 {
     const float min = 0.1f; // this is the minimum number for the float slider of speed
     const float max = 10;   // this is the maximum number for the float slider of speed
     const int ControlHeight = 16; // this is the height of each control line
 
 
     // we check if we are adding a new class to the inspector gui, if so, we add the control height
     // so that the next control goes bellow of our second line of previous control
     public override float GetPropertyHeight(SerializedProperty prop,
                                              GUIContent label)
     {
         return base.GetPropertyHeight(prop, label) + ControlHeight;
     }
 
     public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
     {
         // we go one indent inside to make things nicer
         EditorGUI.indentLevel = 1;
         // we find the same Speed float of the animationClass
         SerializedProperty speed = prop.FindPropertyRelative("Speed");
         // we find the same Animation variable on animationClass
         SerializedProperty anim = prop.FindPropertyRelative("Animation");
         // we check for any change on GUI
         EditorGUI.BeginChangeCheck();
         // Draw Speed slider
         EditorGUI.Slider(new Rect(pos.x, pos.y, pos.width, 15),
                 speed, min, max, label);
         // Now add a lable beside slider so that we know what it do
         EditorGUI.LabelField(new Rect(pos.x +pos.width /2 - 65, pos.y, 60, pos.height), "Speed :");
         //define a new rect
         Rect ExtraPosition = EditorGUI.IndentedRect(pos);
         // now we want to put things in second line
         ExtraPosition.y += ControlHeight;
         ExtraPosition.height = ControlHeight+5;
         // now we can add the other stuff here but to make it simpler and more coder friendly
         // for future, i put them in another method
         DrawAnimControls(ExtraPosition, anim, prop,label);
     }
 
     void DrawAnimControls(Rect position, SerializedProperty prop1, SerializedProperty fps, GUIContent label)
     {
         // we check if things changed
         EditorGUI.BeginChangeCheck();
         // we need to devide the width of inspector gui to 2, so that we can add 2 fields there
         position.width = position.width /2 ;
         // Draw Animation Field
         EditorGUI.PropertyField(
             position,
             prop1, GUIContent.none);
         position.x += position.width ;
         // now we add another label so that we know what the enum is about
         
         EditorGUI.LabelField(new Rect(position.x, position.y, 50, position.height), "FPS :");
         // and finally we add the enum to GUI
         // remember that you can't address the enum variable of animClass directly,
         // but if you defiend a variable of type of that enum, then you can search for the
         // name of that variable, here i had : "public AnimationFPS FPS"
         // and with using "fps.FindPropertyRelative("FPS")" i can find that variable
         // and make a property field for that !
         EditorGUI.PropertyField(new Rect(position.x+55, position.y, position.width-55, position.height), fps.FindPropertyRelative("FPS"), GUIContent.none);
     }
 }

remember, i wanted to have the slider in first line and the rest in second line, hence the reason i added that Control Height at GetPropertyHeight method

at the end, i should say that unity document was helpful, but i got the idea of changing height for the lines from the link of the blog post i sent before i hope it helps others like me that had this issue now the only thing i want is to find a way to remake the same [Popup] functionality i saw in that blog post, but i think it's out of my current experiance so can anyone help? have fun

Comment
Add comment · Show 1 · 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 rhys_vdw · Apr 04, 2013 at 06:47 AM 0
Share

Thanks for posting.

avatar image
-1

Answer by Ashkan_gc · Aug 31, 2015 at 10:06 AM

here it is an implementation attributed to Gamajun studio (my employer) with an MIT license to use Here is the drawer

 //(C) Gamajun s.r.o with M.I.T license
 //http://opensource.org/licenses/MIT
 using UnityEngine;
 using System.Collections;
 using UnityEditor;
 
 namespace Our
 {
     [CustomPropertyDrawer(typeof(PopUpAttribute))]
     public class PopUpPropertyDrawer : PropertyDrawer
     {
         private int index = 0;
         public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
         {
             PopUpAttribute items = attribute as PopUpAttribute;
 
             // Now draw the property as a Slider or an IntSlider based on whether it's a float or integer.
             if (property.propertyType == SerializedPropertyType.String)
             {
                 var prevIndex = index;
                 index = EditorGUI.Popup(position, property.displayName, index, items.items);
                 if (prevIndex != index)
                 {
                     property.stringValue = items.items[index];
                 }
             }
             else
                 EditorGUI.LabelField(position, label.text, "Use PopUp for strings.");
         }
 
     }
 }
 


And here is the attribute

 //(C) Gamajun s.r.o M.I.T license
 //http://opensource.org/licenses/MIT
 using UnityEngine;
 using System.Collections;
 
 namespace Our
 {
     public class PopUpAttribute : PropertyAttribute
     {
         public string[] items;
 
         public PopUpAttribute(params string[] args)
         {
             items = args;

         }
     }
 }
 
Comment
Add comment · Show 6 · 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 Mikilo · Aug 31, 2015 at 10:12 AM 0
Share

You should not set param argument "args" in PopUpAttribute as object[] but string[].

This will avoid boxing and unwanted null or cast exception. $$anonymous$$oreover, the compiler will prevent those errors.

Edit: Now you are good to go =D

avatar image Ashkan_gc · Aug 31, 2015 at 12:19 PM 0
Share

Yes for sure, Internally I wanted to make this more flexible and add more types but shared too fast, It's what I get for hurrying up at sharing.

avatar image Ashkan_gc · Aug 31, 2015 at 12:20 PM 0
Share

Yes for sure, Internally I wanted to make this more flexible and add more types but shared too fast, It's what I get for hurrying up at sharing. Type safety is a great thing and I actually don't like dynamic languages at all.

avatar image Mikilo · Aug 31, 2015 at 12:26 PM 0
Share

In fact, you could have use param object[], but ins$$anonymous$$d of casting "as string" you should have used ToString when the element is not null. It works too.

avatar image Ashkan_gc · Aug 31, 2015 at 06:45 PM 1
Share

First of all I forgot to mention that no boxing operation would happen since both object and string are reference types, boxing is the operation of wrapping a value type inside a reference type. Well it could be done using ToString or maybe a few more methods but it wasn't my intention and it was none required work.

Show more comments

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

12 People are following this question.

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

Related Questions

Material doesn't have a color property '_Color' 4 Answers

Unity Property Drawer - Making more space 2 Answers

Simple question about Guitext 1 Answer

Shader property default behavior in inspector 0 Answers

Branching target animations in mecanim 1 Answer


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