Skip to content

Instantly share code, notes, and snippets.

@BennyKok
Last active January 16, 2024 09:51
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BennyKok/f0fdaf68d3074b72562632a0c3d4b193 to your computer and use it in GitHub Desktop.
Save BennyKok/f0fdaf68d3074b72562632a0c3d4b193 to your computer and use it in GitHub Desktop.
//visible[0] is an AnimBool, you can cache it somewhere in your custom editor.
using (new EditorUtils.FoldoutScope(visible[0], out var shouldDraw, "SongItem"))
{
if (shouldDraw)
{
//draw the rest of your GUI.
songItem = EditorGUILayout.ObjectField(songItem, typeof(SongItem), false) as SongItem;
}
}
defaultFoldout = EditorGUILayout.Foldout(defaultFoldout, "Default Foldout", true);
if (defaultFoldout)
{
EditorGUILayout.TextField("Dummy Data", "");
EditorGUILayout.TextField("Dummy Data", "");
}
using System;
using UnityEditor;
using UnityEditor.AnimatedValues;
using UnityEngine;
namespace RhythmGameStarter
{
public static class EditorUtils
{
public readonly struct FoldoutScope : IDisposable
{
private readonly bool wasIndent;
public FoldoutScope(AnimBool value, out bool shouldDraw, string label, bool indent = true, SerializedProperty toggle = null)
{
value.target = Foldout(value.target, label, toggle);
shouldDraw = EditorGUILayout.BeginFadeGroup(value.faded);
if (shouldDraw && indent)
{
Indent();
wasIndent = true;
}
else
{
wasIndent = false;
}
}
public void Dispose()
{
if (wasIndent)
EndIndent();
EditorGUILayout.EndFadeGroup();
}
}
public static void HorizontalLine(float height = 1, float width = -1, Vector2 margin = new Vector2())
{
GUILayout.Space(margin.x);
var rect = EditorGUILayout.GetControlRect(false, height);
if (width > -1)
{
var centerX = rect.width / 2;
rect.width = width;
rect.x += centerX - width / 2;
}
Color color = EditorStyles.label.active.textColor;
color.a = 0.5f;
EditorGUI.DrawRect(rect, color);
GUILayout.Space(margin.y);
}
public static bool Foldout(bool value, string label, SerializedProperty toggle = null)
{
bool _value;
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
EditorGUILayout.BeginHorizontal();
if (toggle != null && !toggle.boolValue)
{
EditorGUI.BeginDisabledGroup(true);
_value = EditorGUILayout.Toggle(value, EditorStyles.foldout);
EditorGUI.EndDisabledGroup();
_value = false;
}
else
{
_value = EditorGUILayout.Toggle(value, EditorStyles.foldout);
}
if (toggle != null)
{
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(toggle, GUIContent.none, GUILayout.Width(20));
if (EditorGUI.EndChangeCheck() && toggle.boolValue)
_value = true;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
var rect = GUILayoutUtility.GetLastRect();
rect.x += 20;
rect.width -= 20;
if (toggle != null && !toggle.boolValue)
{
EditorGUI.BeginDisabledGroup(true);
EditorGUI.LabelField(rect, label, EditorStyles.boldLabel);
EditorGUI.EndDisabledGroup();
}
else
{
EditorGUI.LabelField(rect, label, EditorStyles.boldLabel);
}
return _value;
}
public static void Indent()
{
EditorGUILayout.BeginHorizontal();
GUILayout.Space(16);
EditorGUILayout.BeginVertical();
}
public static void EndIndent()
{
GUILayout.Space(16);
EditorGUILayout.EndVertical();
EditorGUILayout.EndHorizontal();
}
}
}
public FoldoutScope(AnimBool value, out bool shouldDraw, string label, bool indent = true, SerializedProperty toggle = null)
{
value.target = Foldout(value.target, label, toggle);
shouldDraw = EditorGUILayout.BeginFadeGroup(value.faded);
if (shouldDraw && indent)
{
Indent();
wasIndent = true;
}
else
{
wasIndent = false;
}
}
@ATikadze
Copy link

Hey, @BennyKok

Thanks you very much for this code, I've been struggling with it for weeks and finally found a proper foldout.

It works perfectly in the Editor subclass, however I'm having problems in property drawer. If you look at the image the Ads foldout is drawn in a custom editor, however everything underneath is drawn in a property drawer.

Is it possible to use this foldout in property drawers too? Specifically for the 'Settings' foldout in the image. If so, do you have code for that?

Thanks in advance

Screenshot 2023-05-19 at 1 37 58 PM

@BennyKok
Copy link
Author

It would be a bit tricky to use in the property drawer. do you plan to do a custom editor for the Scriptable Object as well? or no?

@ATikadze
Copy link

@BennyKok I managed to do it. The logic for drawing sub-properties of scriptable objects was in the property drawer, however I completely restructured it and now everything is drawn in the editor.

Thanks for the response and for the code 🙌

@BennyKok
Copy link
Author

Thats great to hear!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment