Changing how Animation Curve window looks?

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:

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

instead of this:

3188574--243387--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

    public class RotationTimelineData
    {

        public AnimationCurve Curve;

    }

FIXED IT!

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

   public class RotationTimelineData
    {
        [Curve(5f, 5f)]
        public AnimationCurve Curve;

    }

and that will set a range for the grid!

I’m happy I learned something today!

3 Likes

Hi Alex,
It would be very nice if you could share your PropertyAttribute as I definitely could have use of it too :slight_smile:

Sure! I have an exam in about 20 minutes but I’ll clean it up a bit and post it after that :slight_smile:

3 Likes
// CurveDrawer.cs
// Created by Alexander Ameye
// Version 1.1.0

using UnityEngine;
using UnityEditor;

[CustomPropertyDrawer(typeof(CurveAttribute))]
public class CurveDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        CurveAttribute curve = attribute as CurveAttribute;
        if (property.propertyType == SerializedPropertyType.AnimationCurve)
        {
            if (curve.b) EditorGUI.CurveField(position, property, Color.cyan, new Rect(curve.PosX, curve.PosY, curve.RangeX, curve.RangeY));
        }
    }
}
// CurveAttribute.cs
// Created by Alexander Ameye
// Version 1.1.0

using UnityEngine;

public class CurveAttribute : PropertyAttribute
{
    public float PosX, PosY;
    public float RangeX, RangeY;
    public bool b;
    public int x;

    public CurveAttribute(float PosX, float PosY,float RangeX, float RangeY, bool b)
    {
        this.PosX = PosX;
        this.PosY = PosY;
        this.RangeX = RangeX;
        this.RangeY = RangeY;
        this.b = b;
    }
}

Don’t forget to put CurveDrawer.cs in an editor folder. You can use this code by doing something like:

[Curve(0, 0, 1f, 1f, true)]
        public AnimationCurve RotationCurve;

I picked the curves to be cyan but you can of course choose something else.

Good luck!

16 Likes

Thanks buddy.

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

if (curve.b) EditorGUI.CurveField(position, property, Color.cyan, new Rect(curve.PosX, curve.PosY, curve.RangeX, curve.RangeY), label);
1 Like

Are there anyway we could change background or draw some overlay texture of the popup curve window?

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:

using UnityEngine;

// These compiler flags let you put the script anywhere in your project
#if UNITY_EDITOR
using UnityEditor;
#endif

/// <summary>
/// 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).
/// </summary>
public class AnimationCurveSimpleAttribute : PropertyAttribute
{
    public Rect bbox = new Rect(0f, 0f, 1f, 1f);
    public Color color = Color.green;

    public AnimationCurveSimpleAttribute() { }

    public AnimationCurveSimpleAttribute(Rect bbox)
    {
        this.bbox = bbox;
    }

    public AnimationCurveSimpleAttribute(float xmin, float xmax, float ymin, float ymax)
    {
        bbox = new Rect(xmin, ymin, xmax - xmin, ymax - ymin);
    }

    public AnimationCurveSimpleAttribute(Color color)
    {
        bbox = new Rect(0f, 0f, 1f, 1f);
        this.color = color;
    }
  
    public AnimationCurveSimpleAttribute(float xmin, float xmax, float ymin, float ymax, Color color)
    {
        bbox = new Rect(xmin, ymin, xmax - xmin, ymax - ymin);
        this.color = color;
    }
  
    public AnimationCurveSimpleAttribute(Rect bbox, Color color)
    {
        this.bbox = bbox;
        this.color = color;
    }
}



#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(AnimationCurveSimpleAttribute))]
public class AnimationCurveSimpleDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        AnimationCurveSimpleAttribute curve = attribute as AnimationCurveSimpleAttribute;

        // This attribute should only be used with AnimationCurves
        if (property.propertyType != SerializedPropertyType.AnimationCurve)
            throw new System.Exception("AnimationCurveSimple attribute can only be used with AnimationCurve properties, not " + property.propertyType);

        // Check if the property has an assigned AnimationCurve. Create one if it doesn't.
        // If it does, then make sure it has at least 2 keys to avoid empty curves in the inspector.
        if (property.animationCurveValue == null ? true : property.animationCurveValue.keys.Length <= 1)
            property.animationCurveValue = new AnimationCurve(new Keyframe(curve.bbox.xMin, curve.bbox.center.y), new Keyframe(curve.bbox.xMax, curve.bbox.center.y));

        // Draw the curve in the inspector (this is not the popup editor window)
        EditorGUI.CurveField(position, property, curve.color, curve.bbox, label);
    }
}
#endif

For Editor folder:

using UnityEngine;
using UnityEditor;

[CustomPropertyDrawer(typeof(AnimationCurveSimpleAttribute))]
public class AnimationCurveSimpleDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        AnimationCurveSimpleAttribute curve = attribute as AnimationCurveSimpleAttribute;

        // This attribute should only be used with AnimationCurves
        if (property.propertyType != SerializedPropertyType.AnimationCurve)
            throw new System.Exception("AnimationCurveSimple attribute can only be used with AnimationCurve properties, not " + property.propertyType);

        // Check if the property has an assigned AnimationCurve. Create one if it doesn't.
        // If it does, then make sure it has at least 2 keys to avoid empty curves in the inspector.
        if (property.animationCurveValue == null ? true : property.animationCurveValue.keys.Length <= 1)
            property.animationCurveValue = new AnimationCurve(new Keyframe(curve.bbox.xMin, curve.bbox.center.y), new Keyframe(curve.bbox.xMax, curve.bbox.center.y));
      
        // Draw the curve in the inspector (this is not the popup editor window)
        EditorGUI.CurveField(position, property, curve.color, curve.bbox, label);
    }
}

For anywhere:

using UnityEngine;
/// <summary>
/// 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).
/// </summary>
public class AnimationCurveSimpleAttribute : PropertyAttribute
{
    public Rect bbox = new Rect(0f, 0f, 1f, 1f);
    public Color color = Color.green;

    public AnimationCurveSimpleAttribute() { }

    public AnimationCurveSimpleAttribute(Rect bbox)
    {
        this.bbox = bbox;
    }

    public AnimationCurveSimpleAttribute(float xmin, float xmax, float ymin, float ymax)
    {
        bbox = new Rect(xmin, ymin, xmax - xmin, ymax - ymin);
    }

    public AnimationCurveSimpleAttribute(Color color)
    {
        bbox = new Rect(0f, 0f, 1f, 1f);
        this.color = color;
    }
  
    public AnimationCurveSimpleAttribute(float xmin, float xmax, float ymin, float ymax, Color color)
    {
        bbox = new Rect(xmin, ymin, xmax - xmin, ymax - ymin);
        this.color = color;
    }
  
    public AnimationCurveSimpleAttribute(Rect bbox, Color color)
    {
        this.bbox = bbox;
        this.color = color;
    }
}
1 Like