Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Changing how Animation Curve window looks?

Discussion in 'Scripting' started by alexanderameye, Aug 18, 2017.

  1. alexanderameye

    alexanderameye

    Joined:
    Nov 27, 2013
    Posts:
    1,383
    I have a public AnimationCurve that shows up in the inspector, but I'd like to choose the ranges of the grid manually.

    So when I click on the Animation curve in the inspector window I want this to show up with the grid a certain size etc. This image was created using EditorGUILayout.CurveField. So I need this:

    upload_2017-8-18_21-36-57.png

    instead of this:

    upload_2017-8-18_21-36-5.png


    How can I make it so that when I click on a regular public AnimationCurve in the inspector, the window shows up just as I can make it show up with EditorGUILayout.CurveField?

    Any help is really really appreciated.

    I have this code in a regular non-editor script

    Code (CSharp):
    1.     public class RotationTimelineData
    2.     {
    3.  
    4.         public AnimationCurve Curve;
    5.  
    6.     }
     

    Attached Files:

    Last edited: Aug 18, 2017
  2. alexanderameye

    alexanderameye

    Joined:
    Nov 27, 2013
    Posts:
    1,383
    FIXED IT!

    I had to write a custom PropertyAttribute! Now I can just write this:

    Code (CSharp):
    1.    public class RotationTimelineData
    2.     {
    3.         [Curve(5f, 5f)]
    4.         public AnimationCurve Curve;
    5.  
    6.     }
    and that will set a range for the grid!

    I'm happy I learned something today!
     
    ProbePLayer, rv0000s and Doug_B like this.
  3. kookyoo

    kookyoo

    Joined:
    Apr 19, 2010
    Posts:
    53
    Hi Alex,
    It would be very nice if you could share your PropertyAttribute as I definitely could have use of it too :)
     
  4. alexanderameye

    alexanderameye

    Joined:
    Nov 27, 2013
    Posts:
    1,383
    Sure! I have an exam in about 20 minutes but I'll clean it up a bit and post it after that :)
     
    Egad_McDad, rv0000s and Munchy2007 like this.
  5. alexanderameye

    alexanderameye

    Joined:
    Nov 27, 2013
    Posts:
    1,383
    Code (CSharp):
    1. // CurveDrawer.cs
    2. // Created by Alexander Ameye
    3. // Version 1.1.0
    4.  
    5. using UnityEngine;
    6. using UnityEditor;
    7.  
    8. [CustomPropertyDrawer(typeof(CurveAttribute))]
    9. public class CurveDrawer : PropertyDrawer
    10. {
    11.     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    12.     {
    13.         CurveAttribute curve = attribute as CurveAttribute;
    14.         if (property.propertyType == SerializedPropertyType.AnimationCurve)
    15.         {
    16.             if (curve.b) EditorGUI.CurveField(position, property, Color.cyan, new Rect(curve.PosX, curve.PosY, curve.RangeX, curve.RangeY));
    17.         }
    18.     }
    19. }
    20.  
    Code (CSharp):
    1. // CurveAttribute.cs
    2. // Created by Alexander Ameye
    3. // Version 1.1.0
    4.  
    5. using UnityEngine;
    6.  
    7. public class CurveAttribute : PropertyAttribute
    8. {
    9.     public float PosX, PosY;
    10.     public float RangeX, RangeY;
    11.     public bool b;
    12.     public int x;
    13.  
    14.     public CurveAttribute(float PosX, float PosY,float RangeX, float RangeY, bool b)
    15.     {
    16.         this.PosX = PosX;
    17.         this.PosY = PosY;
    18.         this.RangeX = RangeX;
    19.         this.RangeY = RangeY;
    20.         this.b = b;
    21.     }
    22. }
    23.  
    Don't forget to put CurveDrawer.cs in an editor folder. You can use this code by doing something like:

    Code (CSharp):
    1. [Curve(0, 0, 1f, 1f, true)]
    2.         public AnimationCurve RotationCurve;
    I picked the curves to be cyan but you can of course choose something else.

    Good luck!
     
  6. trooper

    trooper

    Joined:
    Aug 21, 2009
    Posts:
    748
    Thanks buddy.
     
  7. raducristiandimitrie

    raducristiandimitrie

    Joined:
    Nov 6, 2018
    Posts:
    5
    Great work! Thank you!
    I changed your code a little to display the name of the AnimationCurve, since it was blank in the editor:

    Code (CSharp):
    1. if (curve.b) EditorGUI.CurveField(position, property, Color.cyan, new Rect(curve.PosX, curve.PosY, curve.RangeX, curve.RangeY), label);
     
    Michael_Berna likes this.
  8. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,201
    Are there anyway we could change background or draw some overlay texture of the popup curve window?
     
  9. Boof

    Boof

    Joined:
    Aug 11, 2014
    Posts:
    11
    Here is another version for those interested.
    • Color controls in attribute constructor
    • More attribute constructor options
    • Empty AnimationCurves are avoided
    • Raises a System.Exception if the attribute is used on a property which isn't an AnimationCurve.
    • Place the combined script anywhere you like and it will still work because of compiler flags. Otherwise, place the Editor script in the Editor folder and the other script wherever. Unity suggests this, as it might eventually improve compile times, but I personally prefer code portability and I haven't noticed any problems yet.

    Combined script:
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. // These compiler flags let you put the script anywhere in your project
    4. #if UNITY_EDITOR
    5. using UnityEditor;
    6. #endif
    7.  
    8. /// <summary>
    9. /// Forces an AnimationCurve to keep its keys within a certain window. The default is a range of (x0, y0) = (0, 0) to (x1, y1) = (1, 1).
    10. /// </summary>
    11. public class AnimationCurveSimpleAttribute : PropertyAttribute
    12. {
    13.     public Rect bbox = new Rect(0f, 0f, 1f, 1f);
    14.     public Color color = Color.green;
    15.  
    16.     public AnimationCurveSimpleAttribute() { }
    17.  
    18.     public AnimationCurveSimpleAttribute(Rect bbox)
    19.     {
    20.         this.bbox = bbox;
    21.     }
    22.  
    23.     public AnimationCurveSimpleAttribute(float xmin, float xmax, float ymin, float ymax)
    24.     {
    25.         bbox = new Rect(xmin, ymin, xmax - xmin, ymax - ymin);
    26.     }
    27.  
    28.     public AnimationCurveSimpleAttribute(Color color)
    29.     {
    30.         bbox = new Rect(0f, 0f, 1f, 1f);
    31.         this.color = color;
    32.     }
    33.  
    34.     public AnimationCurveSimpleAttribute(float xmin, float xmax, float ymin, float ymax, Color color)
    35.     {
    36.         bbox = new Rect(xmin, ymin, xmax - xmin, ymax - ymin);
    37.         this.color = color;
    38.     }
    39.  
    40.     public AnimationCurveSimpleAttribute(Rect bbox, Color color)
    41.     {
    42.         this.bbox = bbox;
    43.         this.color = color;
    44.     }
    45. }
    46.  
    47.  
    48.  
    49. #if UNITY_EDITOR
    50. [CustomPropertyDrawer(typeof(AnimationCurveSimpleAttribute))]
    51. public class AnimationCurveSimpleDrawer : PropertyDrawer
    52. {
    53.     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    54.     {
    55.         AnimationCurveSimpleAttribute curve = attribute as AnimationCurveSimpleAttribute;
    56.  
    57.         // This attribute should only be used with AnimationCurves
    58.         if (property.propertyType != SerializedPropertyType.AnimationCurve)
    59.             throw new System.Exception("AnimationCurveSimple attribute can only be used with AnimationCurve properties, not " + property.propertyType);
    60.  
    61.         // Check if the property has an assigned AnimationCurve. Create one if it doesn't.
    62.         // If it does, then make sure it has at least 2 keys to avoid empty curves in the inspector.
    63.         if (property.animationCurveValue == null ? true : property.animationCurveValue.keys.Length <= 1)
    64.             property.animationCurveValue = new AnimationCurve(new Keyframe(curve.bbox.xMin, curve.bbox.center.y), new Keyframe(curve.bbox.xMax, curve.bbox.center.y));
    65.  
    66.         // Draw the curve in the inspector (this is not the popup editor window)
    67.         EditorGUI.CurveField(position, property, curve.color, curve.bbox, label);
    68.     }
    69. }
    70. #endif
    For Editor folder:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. [CustomPropertyDrawer(typeof(AnimationCurveSimpleAttribute))]
    5. public class AnimationCurveSimpleDrawer : PropertyDrawer
    6. {
    7.     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    8.     {
    9.         AnimationCurveSimpleAttribute curve = attribute as AnimationCurveSimpleAttribute;
    10.  
    11.         // This attribute should only be used with AnimationCurves
    12.         if (property.propertyType != SerializedPropertyType.AnimationCurve)
    13.             throw new System.Exception("AnimationCurveSimple attribute can only be used with AnimationCurve properties, not " + property.propertyType);
    14.  
    15.         // Check if the property has an assigned AnimationCurve. Create one if it doesn't.
    16.         // If it does, then make sure it has at least 2 keys to avoid empty curves in the inspector.
    17.         if (property.animationCurveValue == null ? true : property.animationCurveValue.keys.Length <= 1)
    18.             property.animationCurveValue = new AnimationCurve(new Keyframe(curve.bbox.xMin, curve.bbox.center.y), new Keyframe(curve.bbox.xMax, curve.bbox.center.y));
    19.      
    20.         // Draw the curve in the inspector (this is not the popup editor window)
    21.         EditorGUI.CurveField(position, property, curve.color, curve.bbox, label);
    22.     }
    23. }
    For anywhere:
    Code (CSharp):
    1. using UnityEngine;
    2. /// <summary>
    3. /// Forces an AnimationCurve to keep its keys within a certain window. The default is a range of (x0, y0) = (0, 0) to (x1, y1) = (1, 1).
    4. /// </summary>
    5. public class AnimationCurveSimpleAttribute : PropertyAttribute
    6. {
    7.     public Rect bbox = new Rect(0f, 0f, 1f, 1f);
    8.     public Color color = Color.green;
    9.  
    10.     public AnimationCurveSimpleAttribute() { }
    11.  
    12.     public AnimationCurveSimpleAttribute(Rect bbox)
    13.     {
    14.         this.bbox = bbox;
    15.     }
    16.  
    17.     public AnimationCurveSimpleAttribute(float xmin, float xmax, float ymin, float ymax)
    18.     {
    19.         bbox = new Rect(xmin, ymin, xmax - xmin, ymax - ymin);
    20.     }
    21.  
    22.     public AnimationCurveSimpleAttribute(Color color)
    23.     {
    24.         bbox = new Rect(0f, 0f, 1f, 1f);
    25.         this.color = color;
    26.     }
    27.  
    28.     public AnimationCurveSimpleAttribute(float xmin, float xmax, float ymin, float ymax, Color color)
    29.     {
    30.         bbox = new Rect(xmin, ymin, xmax - xmin, ymax - ymin);
    31.         this.color = color;
    32.     }
    33.  
    34.     public AnimationCurveSimpleAttribute(Rect bbox, Color color)
    35.     {
    36.         this.bbox = bbox;
    37.         this.color = color;
    38.     }
    39. }