Last active
February 16, 2021 19:50
-
-
Save yagero/0a3812498bee0438541d64c8665c6076 to your computer and use it in GitHub Desktop.
EditorGUILayout Fields which properly handles multi-object editing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UnityEngine; | |
using UnityEditor; | |
public static class EditorGUILayoutExtensions | |
{ | |
/// <summary> | |
/// Add a EditorGUILayout.ToggleLeft which properly handles multi-object editing | |
/// </summary> | |
public static void ToggleLeft(this SerializedProperty prop, GUIContent label, params GUILayoutOption[] options) | |
{ | |
EditorGUI.BeginChangeCheck(); | |
EditorGUI.showMixedValue = prop.hasMultipleDifferentValues; | |
var newValue = EditorGUILayout.ToggleLeft(label, prop.boolValue, options); | |
EditorGUI.showMixedValue = false; | |
if (EditorGUI.EndChangeCheck()) | |
prop.boolValue = newValue; | |
} | |
/// <summary> | |
/// Create a EditorGUILayout.Slider which properly handles multi-object editing | |
/// We apply the 'convIn' conversion to the SerializedProperty value before exposing it as a Slider. | |
/// We apply the 'convOut' conversion to the Slider value to store it back to the SerializedProperty. | |
/// </summary> | |
/// <param name="prop">The value the slider shows. This determines the position of the draggable thumb.</param> | |
/// <param name="label">Label in front of the slider.</param> | |
/// <param name="leftValue">The value at the left end of the slider.</param> | |
/// <param name="rightValue">The value at the right end of the slider.</param> | |
/// <param name="convIn">Conversion function applied on the SerializedProperty to get the Slider value</param> | |
/// <param name="convOut">Conversion function applied on the Slider value to get the SerializedProperty</param> | |
public static void FloatSlider( | |
this SerializedProperty prop, | |
GUIContent label, | |
float leftValue, float rightValue, | |
Func<float, float> convIn, | |
Func<float, float> convOut, | |
params GUILayoutOption[] options) | |
{ | |
var floatValue = convIn(prop.floatValue); | |
EditorGUI.BeginChangeCheck(); | |
{ | |
EditorGUI.showMixedValue = prop.hasMultipleDifferentValues; | |
{ | |
floatValue = EditorGUILayout.Slider(label, floatValue, leftValue, rightValue, options); | |
} | |
EditorGUI.showMixedValue = false; | |
} | |
if (EditorGUI.EndChangeCheck()) | |
prop.floatValue = convOut(floatValue); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEditor; | |
using UnityEngine; | |
[CustomEditor(typeof(UsageExample))] | |
[CanEditMultipleObjects] | |
public class UsageExampleEditor : Editor | |
{ | |
SerializedProperty propBool; | |
SerializedProperty propFloat; | |
void OnEnable() | |
{ | |
propBool = serializedObject.FindProperty("MyBoolProp"); | |
propFloat = serializedObject.FindProperty("MyFloatProp"); | |
} | |
public override void OnInspectorGUI() | |
{ | |
serializedObject.Update(); | |
/////////////////////////////////////////////// | |
// HOW TO PROPERLY EXPOSE A TOGGLE LEFT | |
/////////////////////////////////////////////// | |
// /!\ THIS CODE DOESN'T PROPERLY HANDLE MULTI-OBJECT EDITING /!\ | |
propBool.boolValue = EditorGUILayout.ToggleLeft("My Bool", propBool.boolValue); | |
// THIS IS HOW YOU PROPERLY HANDLE MULTI-OBJECT EDITING | |
EditorGUI.BeginChangeCheck(); | |
EditorGUI.showMixedValue = propBool.hasMultipleDifferentValues; | |
var newValue = EditorGUILayout.ToggleLeft("My Bool", propBool.boolValue); | |
EditorGUI.showMixedValue = false; | |
if (EditorGUI.EndChangeCheck()) | |
propBool.boolValue = newValue; | |
// OR USE THIS EXTENSION METHOD | |
propBool.ToggleLeft(new GUIContent("My Bool")); | |
////////////////////////////////////////////////////////////// | |
// HOW TO PROPERLY EXPOSE A FLOAT SLIDER WITH SOME CONVERSION | |
// for example we want to expose 1/value as a slider | |
////////////////////////////////////////////////////////////// | |
// /!\ THIS CODE DOESN'T PROPERLY HANDLE MULTI-OBJECT EDITING /!\ | |
var exposedFloatValue = 1f / propFloat.floatValue; | |
exposedFloatValue = EditorGUILayout.Slider("My Float", exposedFloatValue, 0.1f, 1.0f); | |
propFloat.floatValue = 1f / exposedFloatValue; | |
// USE THIS NICE EXTENSION METHOD INSTEAD :) | |
propFloat.FloatSlider( | |
new GUIContent("My Float"), | |
0.1f, 1.0f, | |
(v) => 1f / v, // conversion SerializedProperty => Slider | |
(v) => 1f / v); // conversion Slider => SerializedProperty | |
serializedObject.ApplyModifiedProperties(); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment