您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
275 行
10 KiB
275 行
10 KiB
using UnityEngine;
|
|
using UnityEngine.VFXToolbox;
|
|
using System.Collections.Generic;
|
|
|
|
namespace UnityEditor.Experimental.VFX.Toolbox
|
|
{
|
|
internal class CurveDrawer
|
|
{
|
|
private string m_CurveEditName;
|
|
private int m_WidgetDefaultHeight;
|
|
private bool m_WidgetShowToolbar;
|
|
private readonly RectOffset m_CurvePadding = new RectOffset(40, 16, 16, 16);
|
|
private CurveEditor m_Editor;
|
|
private Dictionary<string, SerializedProperty> m_Curves;
|
|
|
|
public delegate void CurveDrawEventDelegate(Rect renderArea, Rect curveArea);
|
|
public CurveDrawEventDelegate OnPostGUI;
|
|
|
|
private float lineBrightnessValue { get { return EditorGUIUtility.isProSkin ? 1.0f : 0.0f; } }
|
|
|
|
public CurveDrawer(string curveEditName, float minInput, float maxInput, float minOutput, float maxOutput, int height, bool showToolbar)
|
|
:this(curveEditName, minInput, maxInput, minOutput, maxOutput)
|
|
{
|
|
m_WidgetDefaultHeight = height;
|
|
m_WidgetShowToolbar = showToolbar;
|
|
}
|
|
|
|
public CurveDrawer(string curveEditName, float minInput, float maxInput, float minOutput, float maxOutput)
|
|
{
|
|
var settings = CurveEditor.Settings.defaultSettings;
|
|
settings.bounds = new Rect(minInput, minOutput, maxInput - minInput, maxOutput - minOutput);
|
|
settings.padding = m_CurvePadding;
|
|
m_Editor = new CurveEditor(settings);
|
|
m_CurveEditName = curveEditName;
|
|
m_WidgetDefaultHeight = 240;
|
|
m_WidgetShowToolbar = true;
|
|
m_Curves = new Dictionary<string, SerializedProperty>();
|
|
}
|
|
|
|
public void SetBounds(Rect bounds)
|
|
{
|
|
m_Editor.SetBounds(bounds);
|
|
}
|
|
|
|
public void ClearSelection()
|
|
{
|
|
m_Editor.ClearSelection();
|
|
}
|
|
|
|
public void AddCurve(SerializedProperty curveProperty, Color curveColor, string name, bool visible = true)
|
|
{
|
|
if (m_Curves.ContainsKey(name))
|
|
return;
|
|
|
|
var state = CurveEditor.CurveState.defaultState;
|
|
state.color = curveColor;
|
|
state.minPointCount = 2;
|
|
|
|
m_Curves.Add(name, curveProperty);
|
|
m_Editor.Add(curveProperty, state);
|
|
}
|
|
|
|
public void RemoveCurve(string name)
|
|
{
|
|
if (!m_Curves.ContainsKey(name))
|
|
return;
|
|
m_Editor.Remove(m_Curves[name]);
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
m_Curves.Clear();
|
|
m_Editor.RemoveAll();
|
|
}
|
|
|
|
public bool OnGUI(Rect drawRect)
|
|
{
|
|
return m_Editor.OnGUI(drawRect);
|
|
}
|
|
|
|
public bool OnGUILayout()
|
|
{
|
|
return OnGUILayout(m_WidgetDefaultHeight, m_WidgetShowToolbar);
|
|
}
|
|
|
|
public bool OnGUILayout(bool showToolbar)
|
|
{
|
|
return OnGUILayout(m_WidgetDefaultHeight, showToolbar);
|
|
}
|
|
|
|
public bool OnGUILayout(float height, bool showToolbar)
|
|
{
|
|
bool dirty = false;
|
|
using (new GUILayout.VerticalScope())
|
|
{
|
|
// Header
|
|
if(m_CurveEditName != null || m_CurveEditName == "")
|
|
GUILayout.Label(m_CurveEditName);
|
|
|
|
GUILayout.Space(4.0f);
|
|
|
|
// Curve Area
|
|
if(showToolbar)
|
|
{
|
|
using (new GUILayout.HorizontalScope(EditorStyles.toolbar))
|
|
{
|
|
foreach(KeyValuePair<string,SerializedProperty> kvp in m_Curves)
|
|
{
|
|
string name = kvp.Key;
|
|
SerializedProperty curve = kvp.Value;
|
|
CurveEditor.CurveState state = m_Editor.GetCurveState(curve);
|
|
bool b = GUILayout.Toggle(state.visible, name, EditorStyles.toolbarButton);
|
|
if (b != state.visible)
|
|
{
|
|
state.visible = b;
|
|
m_Editor.SetCurveState(curve, state);
|
|
}
|
|
}
|
|
GUILayout.FlexibleSpace();
|
|
}
|
|
}
|
|
|
|
Rect lastRect = GUILayoutUtility.GetLastRect();
|
|
Rect curveArea = GUILayoutUtility.GetRect(lastRect.width, height);
|
|
|
|
// Selection
|
|
CurveEditor.Selection selection = m_Editor.GetSelection();
|
|
if(selection.curve != null && selection.keyframe != null)
|
|
{
|
|
EditorGUI.indentLevel ++;
|
|
var key = selection.keyframe.Value;
|
|
Rect range = m_Editor.settings.bounds;
|
|
float t = EditorGUILayout.Slider("Time", key.time, range.xMin, range.xMax);
|
|
float v = EditorGUILayout.Slider("Value", key.value, range.yMin, range.yMax);
|
|
float inTgt = EditorGUILayout.FloatField("In Tangent", key.inTangent);
|
|
float outTgt = EditorGUILayout.FloatField("Out Tangent", key.outTangent);
|
|
|
|
if(t != key.time || v != key.value || inTgt != key.inTangent || outTgt != key.outTangent)
|
|
{
|
|
Keyframe newkey = new Keyframe(t,v,inTgt, outTgt);
|
|
m_Editor.SetKeyframe(selection.curve, selection.keyframeIndex, newkey);
|
|
}
|
|
EditorGUI.indentLevel--;
|
|
}
|
|
|
|
// Canvas
|
|
DrawCurveCanvas(curveArea);
|
|
dirty = m_Editor.OnGUI(curveArea);
|
|
|
|
|
|
}
|
|
return dirty;
|
|
}
|
|
|
|
public void DrawCurveCanvas(Rect rect)
|
|
{
|
|
EditorGUI.DrawRect(rect, new Color(0, 0, 0, 0.25f));
|
|
if(Event.current.type == EventType.Layout)
|
|
return;
|
|
|
|
GUI.BeginClip(rect);
|
|
|
|
Rect area = new Rect(Vector2.zero, rect.size);
|
|
rect = m_CurvePadding.Remove(area);
|
|
|
|
Rect bounds = m_Editor.settings.bounds;
|
|
float minInput = bounds.xMin;
|
|
float maxInput = bounds.xMax;
|
|
float minOutput = bounds.yMin;
|
|
float maxOutput = bounds.yMax;
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Draw Origins
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
float l = lineBrightnessValue;
|
|
|
|
Handles.color = new Color(l, l, l, 0.2f);
|
|
Handles.DrawLine(new Vector2(rect.xMin, area.yMin), new Vector2(rect.xMin, area.yMax));
|
|
Handles.DrawLine(new Vector2(area.xMin, rect.yMax), new Vector2(area.xMax, rect.yMax));
|
|
Handles.DrawLine(new Vector2(rect.xMax, area.yMin), new Vector2(rect.xMax, area.yMax));
|
|
Handles.DrawLine(new Vector2(area.xMin, rect.yMin), new Vector2(area.xMax, rect.yMin));
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Draw Zero Axis'es
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
if(minInput < 0 && maxInput > 0)
|
|
{
|
|
Handles.color = new Color(l, l, l, 0.6f);
|
|
Handles.DrawLine(new Vector2(0,rect.yMin),new Vector2(0,rect.yMax));
|
|
}
|
|
|
|
if(minOutput < 0 && maxOutput > 0)
|
|
{
|
|
Handles.color = new Color(l, l, l, 0.6f);
|
|
Handles.DrawLine(new Vector2(rect.xMin,0),new Vector2(rect.xMax, 0));
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Draw Grid By Step
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
Handles.color = new Color(l, l, l, 0.05f);
|
|
|
|
for(int i = 1; i < 8; i++) // Verticals
|
|
{
|
|
float step = Mathf.Lerp(rect.xMin, rect.xMax,(float)i / 8);
|
|
Handles.DrawLine(new Vector2(step, area.yMin), new Vector2(step, area.yMax));
|
|
}
|
|
|
|
for(int i = 1; i < 4; i++) // Horizontals
|
|
{
|
|
float step = Mathf.Lerp(rect.yMin, rect.yMax,(float)i / 4);
|
|
Handles.DrawLine(new Vector2(area.xMin, step), new Vector2(area.xMax, step));
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Texts
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
Rect minInRect = new Rect(rect.xMin, rect.yMax, 40, 12);
|
|
Rect maxInRect = new Rect(rect.xMax-40, rect.yMax, 40, 12);
|
|
Rect minOutRect = new Rect(rect.xMin-40, rect.yMax-12, 40, 12);
|
|
Rect maxOutRect = new Rect(rect.xMin-40, rect.yMin, 40, 12);
|
|
|
|
GUI.Label(minInRect, minInput.ToString("F2"), styles.smallLabelLeftAlign);
|
|
GUI.Label(maxInRect, maxInput.ToString("F2"), styles.smallLabelRightAlign);
|
|
GUI.Label(minOutRect, minOutput.ToString("F2"), styles.smallLabelRightAlign);
|
|
GUI.Label(maxOutRect, maxOutput.ToString("F2"), styles.smallLabelRightAlign);
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Text on Zero Axis'es
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
if(minInput < 0 && maxInput > 0)
|
|
{
|
|
Handles.color = new Color(l, l, l, 0.6f);
|
|
Handles.DrawLine(new Vector2(0,rect.yMin), new Vector2(0,rect.yMax));
|
|
}
|
|
|
|
if(minOutput < 0 && maxOutput > 0)
|
|
{
|
|
Handles.color = new Color(l, l, l, 0.6f);
|
|
Handles.DrawLine(new Vector2(rect.xMin,0),new Vector2(rect.xMax, 0));
|
|
}
|
|
|
|
// Custom delegate
|
|
if (OnPostGUI != null)
|
|
OnPostGUI(area, rect);
|
|
|
|
GUI.EndClip();
|
|
}
|
|
|
|
#region Styles
|
|
public Styles styles { get { if (m_Styles == null) m_Styles = new Styles(); return m_Styles; } }
|
|
private Styles m_Styles;
|
|
|
|
public class Styles
|
|
{
|
|
public GUIStyle smallLabelLeftAlign;
|
|
public GUIStyle smallLabelRightAlign;
|
|
|
|
public Styles()
|
|
{
|
|
smallLabelLeftAlign = new GUIStyle(EditorStyles.miniLabel);
|
|
smallLabelLeftAlign.alignment = TextAnchor.MiddleLeft;
|
|
smallLabelRightAlign = new GUIStyle(EditorStyles.miniLabel);
|
|
smallLabelRightAlign.alignment = TextAnchor.MiddleRight;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|