summaryrefslogtreecommitdiff
path: root/Assets/Scripts/Editor/InspectorUtility.cs
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2021-09-20 00:42:33 +0800
committerchai <chaifix@163.com>2021-09-20 00:42:33 +0800
commit02b44c07adfcf921da594120b4cd8fc18b982725 (patch)
tree723e001ed8c5f7c39419cc4a50a3202a0cf59961 /Assets/Scripts/Editor/InspectorUtility.cs
parentd4581317f904b870c482a3274e7cc47d1732a673 (diff)
+command buffer
Diffstat (limited to 'Assets/Scripts/Editor/InspectorUtility.cs')
-rw-r--r--Assets/Scripts/Editor/InspectorUtility.cs169
1 files changed, 169 insertions, 0 deletions
diff --git a/Assets/Scripts/Editor/InspectorUtility.cs b/Assets/Scripts/Editor/InspectorUtility.cs
new file mode 100644
index 00000000..5c1e6e05
--- /dev/null
+++ b/Assets/Scripts/Editor/InspectorUtility.cs
@@ -0,0 +1,169 @@
+using UnityEngine;
+using UnityEditor;
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+/// <summary>
+/// Collection of tools and helpers for drawing inspectors
+/// </summary>
+public class InspectorUtility
+{
+ /// <summary>Put multiple properties on a single inspector line, with
+ /// optional label overrides. Passing null as a label (or sublabel) override will
+ /// cause the property's displayName to be used as a label. For no label at all,
+ /// pass GUIContent.none.</summary>
+ /// <param name="rect">Rect in which to draw</param>
+ /// <param name="label">Main label</param>
+ /// <param name="props">Properties to place on the line</param>
+ /// <param name="subLabels">Sublabels for the properties</param>
+ public static void MultiPropertyOnLine(
+ Rect rect,
+ GUIContent label,
+ SerializedProperty[] props, GUIContent[] subLabels)
+ {
+ if (props == null || props.Length == 0)
+ return;
+
+ const int hSpace = 2;
+ int indentLevel = EditorGUI.indentLevel;
+ float labelWidth = EditorGUIUtility.labelWidth;
+
+ float totalSubLabelWidth = 0;
+ int numBoolColumns = 0;
+ List<GUIContent> actualLabels = new List<GUIContent>();
+ for (int i = 0; i < props.Length; ++i)
+ {
+ GUIContent sublabel = new GUIContent(props[i].displayName, props[i].tooltip);
+ if (subLabels != null && subLabels.Length > i && subLabels[i] != null)
+ sublabel = subLabels[i];
+ actualLabels.Add(sublabel);
+ totalSubLabelWidth += GUI.skin.label.CalcSize(sublabel).x;
+ if (i > 0)
+ totalSubLabelWidth += hSpace;
+ // Special handling for toggles, or it looks stupid
+ if (props[i].propertyType == SerializedPropertyType.Boolean)
+ {
+ totalSubLabelWidth += rect.height;
+ ++numBoolColumns;
+ }
+ }
+
+ float subFieldWidth = rect.width - labelWidth - totalSubLabelWidth;
+ float numCols = props.Length - numBoolColumns;
+ float colWidth = numCols == 0 ? 0 : subFieldWidth / numCols;
+
+ // Main label. If no first sublabel, then main label must take on that
+ // role, for mouse dragging value-scrolling support
+ int subfieldStartIndex = 0;
+ if (label == null)
+ label = new GUIContent(props[0].displayName, props[0].tooltip);
+ if (actualLabels[0] != GUIContent.none)
+ rect = EditorGUI.PrefixLabel(rect, label);
+ else
+ {
+ rect.width = labelWidth + colWidth;
+ EditorGUI.PropertyField(rect, props[0], label);
+ rect.x += rect.width + hSpace;
+ subfieldStartIndex = 1;
+ }
+
+ for (int i = subfieldStartIndex; i < props.Length; ++i)
+ {
+ EditorGUI.indentLevel = 0;
+ EditorGUIUtility.labelWidth = GUI.skin.label.CalcSize(actualLabels[i]).x;
+ if (props[i].propertyType == SerializedPropertyType.Boolean)
+ {
+ rect.width = EditorGUIUtility.labelWidth + rect.height;
+ props[i].boolValue = EditorGUI.ToggleLeft(rect, actualLabels[i], props[i].boolValue);
+ }
+ else
+ {
+ rect.width = EditorGUIUtility.labelWidth + colWidth;
+ EditorGUI.PropertyField(rect, props[i], actualLabels[i]);
+ }
+ rect.x += rect.width + hSpace;
+ }
+
+ EditorGUIUtility.labelWidth = labelWidth;
+ EditorGUI.indentLevel = indentLevel;
+ }
+
+ /// <summary>
+ /// Normalize a curve so that each of X and Y axes ranges from 0 to 1
+ /// </summary>
+ /// <param name="curve">Curve to normalize</param>
+ /// <returns>The normalized curve</returns>
+ public static AnimationCurve NormalizeCurve(AnimationCurve curve)
+ {
+ Keyframe[] keys = curve.keys;
+ if (keys.Length > 0)
+ {
+ float minTime = keys[0].time;
+ float maxTime = minTime;
+ float minVal = keys[0].value;
+ float maxVal = minVal;
+ for (int i = 0; i < keys.Length; ++i)
+ {
+ minTime = Mathf.Min(minTime, keys[i].time);
+ maxTime = Mathf.Max(maxTime, keys[i].time);
+ minVal = Mathf.Min(minVal, keys[i].value);
+ maxVal = Mathf.Max(maxVal, keys[i].value);
+ }
+ float range = maxTime - minTime;
+ float timeScale = range < 0.0001f ? 1 : 1 / range;
+ range = maxVal - minVal;
+ float valScale = range < 1 ? 1 : 1 / range;
+ float valOffset = 0;
+ if (range < 1)
+ {
+ if (minVal > 0 && minVal + range <= 1)
+ valOffset = minVal;
+ else
+ valOffset = 1 - range;
+ }
+ for (int i = 0; i < keys.Length; ++i)
+ {
+ keys[i].time = (keys[i].time - minTime) * timeScale;
+ keys[i].value = ((keys[i].value - minVal) * valScale) + valOffset;
+ }
+ curve.keys = keys;
+ }
+ return curve;
+ }
+
+ /// <summary>
+ /// Remove the "Cinemachine" prefix, then call the standard Unity Nicify.
+ /// </summary>
+ /// <param name="name">The name to nicify</param>
+ /// <returns>The nicified name</returns>
+ public static string NicifyClassName(string name)
+ {
+ if (name.StartsWith("Cinemachine"))
+ name = name.Substring(11); // Trim the prefix
+ return ObjectNames.NicifyVariableName(name);
+ }
+
+ // Temporarily here
+ /// <summary>
+ /// Create a game object. Uses ObjectFactory if the Unity version is sufficient.
+ /// </summary>
+ /// <param name="name">Name to give the object</param>
+ /// <param name="types">Optional components to add</param>
+ /// <returns></returns>
+ public static GameObject CreateGameObject(string name, params Type[] types)
+ {
+ return ObjectFactory.CreateGameObject(name, types);
+ }
+
+ /// <summary>
+ /// Force a repaint of the Game View
+ /// </summary>
+ /// <param name="unused">Like it says</param>
+ public static void RepaintGameView(UnityEngine.Object unused = null)
+ {
+ EditorApplication.QueuePlayerLoopUpdate();
+ UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
+ }
+
+}