Can I clamp an AnimationCurve editor window to specific bounds ?

Hi - We use AnimationCurve values for a lot of our gameplay tweak values. Whenever our designers click on an AnimationCurve to edit it the window which appears is clamped to the extents of the values in the curve. Is there a way to clamp to range to a different value ? Our designers are going bonkers having to constantly reset the zoom levels on the axes.

Thanks.

Hi - you can use the middle mouse to zoom in and out and F to re-frame the curves, but at the moment there is no range value that can be set, to the best of my knowlegde - have it put on feedback and try and get it voted on as much as possible :wink:

http://feedback.unity3d.com/

sorry to open an old thread but has this been achieved yet. i am after something very similar i would like to clamp the values of an animation curve.

You can create a custom editor and clamp the curve there. The example below clamps the curve to a normalized range ([0, 1]) in x- and y-direction.

data.Mask.Curve = EditorGUILayout.CurveField(data.Mask.Curve, Color.red, new Rect(0, 0, 1, 1));
2 Likes

Hello, I found this and decided to show the full code

BoundedCurveAttribute.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BoundedCurveAttribute : PropertyAttribute
{
  public Rect bounds;
  public int height;

  public BoundedCurveAttribute(Rect bounds, int height = 1)
  {
    this.bounds = bounds;
    this.height = height;
  }

  public BoundedCurveAttribute(int height = 1)
  {
    this.bounds = new Rect(0, 0, 1, 1);
    this.height = height;
  }
}

Editor/BoundedCurveDrawer.cs

using UnityEngine;
using UnityEditor;

[CustomPropertyDrawer(typeof(BoundedCurveAttribute))]
public class BoundedCurveDrawer : PropertyDrawer
{
  public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
  {
    BoundedCurveAttribute boundedCurve = (BoundedCurveAttribute)attribute;
    return EditorGUIUtility.singleLineHeight * boundedCurve.height;
  }

  public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
  {
    BoundedCurveAttribute boundedCurve = (BoundedCurveAttribute)attribute;

    EditorGUI.BeginProperty(position, label, property);
    property.animationCurveValue = EditorGUI.CurveField(
      position,
      label,
      property.animationCurveValue,
      Color.white,
      boundedCurve.bounds
     );
    EditorGUI.EndProperty();
  }
}
1 Like

Thank you very much! Although, Iā€™m having trouble using it. The code below gives the error: Attribute constructor parameter ā€˜boundsā€™ has type ā€˜Rectā€™, which is not a valid attribute parameter type.

[BoundedCurve(new Rect(0, 0, 1, 1), 2)][SerializeField] AnimationCurve pinWeightCurve;

I replaced the faulty constructor in BoundedAttributes.cs with the following code:

public BoundedCurveAttribute(float xMin, float yMin, float xMax, float yMax, int height = 1) {
        this.bounds = new Rect(xMin, yMin, xMax, yMax);
        this.guiHeight = height;
    }

Edit: Added a new constructor where we only need the max size

public BoundedCurveAttribute(float xMax, float yMax, int height = 1) {
        this.bounds = new Rect(0, 0, xMax, yMax);
        this.guiHeight = height;
    }
1 Like

Good catch, Iā€™ve somehow only used the other constructor this whole time

This code works really well, although Iā€™ve noticed an issue that I cannot, for the life of me, find out how to fix.
When opening the curve in a custom Inspector using ā€œEditorGUILayout.PropertyField();ā€ full-screening another window, like the game window returns an error reading:
ā€œInvalid editor window of type: UnityEditor.CurveEditorWindow, title: Curveā€
ā€œUnityEditor.EditorApplication:Internal_CallDelayFunctions ()ā€
Iā€™m not sure how the other windows effect the curve window that I already closed, but Iā€™d imagine itā€™s just how Unity manages editor window calls.

If anyone could help it would be a life-saver!

Oh, Iā€™ve also noticed that error, but didnā€™t know it was caused by my code.

This is probably a bug in CurveField, but I wouldnā€™t know where to begin.

Maybe adding some check in OnGUI that the window is actually displayed? Or checking the value of position in situation where errors are thrown ?

It sucks that there hasnā€™t been any solutions to this issue in all this time, how hard is it for Unity to set bounds for an animation curve? Super frustrating