- Home /
Particle System Toggle in Custom editor
The custom toggle and foldout function in the Particle System works very fine. Is there a "EditorGUILayout" way to replicate this in my own custom editor?
Ok i know what you mean i already have that. But when you add the Particle System component you see that it has a much nicer usercontrol. In 1 rectangle they have both a toggle checkbox and a button.
The toggle is used as an activator and the button function in the rectangle has the "toggle" function.
Answer by Bago · Dec 10, 2012 at 11:05 PM
Hey Guys! I think i made a version as close as i can get to the particle system version in this little time with the code Loiuzein has provided!
The Foldout method now contains a ref bool toggled so the toggle is contained and handled in the same code! But i'm not sure if it can be trouble when the return is hit before EndHorizontal() is handled, but i think its not a big issue.
using UnityEngine; using UnityEditor; static class GUIUtils { ///////////////////////////////////////////////////////////////////////////// /* * This section makes an EditorGUILayout.Foldout, except you can actually click anywhere on the word to open it * instead of having to click on the teeny-tiny triangle. * * ... what the bananas, Unity */ private static GUIStyle openFoldoutStyle; private static GUIStyle closedFoldoutStyle; private static bool initted;
private static void Init()
{
openFoldoutStyle = new GUIStyle(GUI.skin.FindStyle("Button"));
openFoldoutStyle.fontStyle = (FontStyle)1;
openFoldoutStyle.stretchHeight = true;
closedFoldoutStyle = new GUIStyle(openFoldoutStyle);
openFoldoutStyle.normal = openFoldoutStyle.onNormal;
openFoldoutStyle.active = openFoldoutStyle.onActive;
initted = true;
}
public static bool Foldout(bool open, ref bool toggled, string text) { return Foldout(open, ref toggled, new GUIContent(text)); }
public static bool Foldout(bool open, ref bool toggled, GUIContent text)
{
if (!initted) Init();
if (open)
{
GUILayout.BeginHorizontal();
toggled = GUILayout.Toggle(toggled, "", GUILayout.Width(30));
if (GUILayout.Button(text, openFoldoutStyle, GUILayout.Height(20), GUILayout.ExpandWidth(true)))
{
GUI.FocusControl("");
GUI.changed = false; // force change-checking group to take notice
GUI.changed = true;
return false;
}
GUILayout.EndHorizontal();
}
else
{
GUILayout.BeginHorizontal();
toggled = GUILayout.Toggle(toggled, "", GUILayout.Width(30));
if (GUILayout.Button(text, closedFoldoutStyle, GUILayout.Height(20)))
{
GUI.FocusControl("");
GUI.changed = false; // force change-checking to take notice
GUI.changed = true;
return true;
}
GUILayout.EndHorizontal();
}
return open;
}
}
As a note to that, IF you're using Editor-style change checking (BeginChangeCheck or GUI.Changed), toggling the Toggle control might not trigger the change check (see how inside the button field I had to flip GUI.changed back and forth to get it to register).
Answer by Jake.OConnor · Dec 10, 2012 at 04:10 PM
What you're looking for is EditorGUILayout.Foldout(), which returns a bool value whether or not it is toggled. Then use a simple if statement to check if the value is true or not, and if it is draw the rest of your EditorGUILayout stuff inside. It will have the same effect as the built-in Unity editors.
< Edit >
I see what you want now (had to add a new Particle System in order to see it). You're going to want to nest both a Foldout and ToggleGroup both inside of a BeginHorizontal()-EndHorizontal(). Then you can use the returns from the Foldout and ToggleGroup in order to organize things in the manner you're looking for. This may be a little messy below, just a warning. It should get you on the right track though. Play around with it a little, the EditorGUI in unity is really powerful.
EditorGUILayout.BeginHorizontal();
unfolded = EditorGUILayout.Foldout( unfolded, "" );
posGroupEnabled = EditorGUILayout.BeginToggleGroup("Align position", posGroupEnabled);
EditorGUILayout.EndHoritontal();
if(unfolded)
{
pos[0] = EditorGUILayout.Toggle("x", pos[0]);
pos[1] = EditorGUILayout.Toggle("y", pos[1]);
pos[2] = EditorGUILayout.Toggle("z", pos[2]);
}
EditorGUILayout.EndToggleGroup();
Ok ok i know how it works and indeed you know what i want :P but the look and feel of the control is better than how this works.
The rectangle on the background reacts when the user clicks and is used as the "foldout" function. So it's like the toggle is embedded in the rectangle. I know how BeginHorizontal works but i dont know if i can embed other stuff inside a "button"/"rectangle" like how it works in the particle system.
I don't think you could make it look like the Particle System editor without some significant work on your part. I don't believe that EditorGUILayout can do it, but I'm sure you could do it with plain EditorGUI using nested and overlapped labels and textures to achieve the colorization you want. For the time being, I think the best solution would just be to make a comparable menu with EditorGUILayout.
Answer by Loius · Dec 10, 2012 at 08:59 PM
I got tired of trying to hit that tiny triangle to open GUI.Foldout controls, so I wrote a Foldout of my own. You can click anywhere in the region (from the triangle all the way to the end of the text area) to open/close this foldout. If you don't like the bold font, just comment out the 'fontStyle = ' line.
This won't work in-game unless you have a 'Foldout' style in your skin. (The default EditorGUI skin already has one)
using UnityEngine;
using UnityEditor;
static class GUIUtils {
/////////////////////////////////////////////////////////////////////////////
/*
* This section makes an EditorGUILayout.Foldout, except you can actually click anywhere on the word to open it
* instead of having to click on the teeny-tiny triangle.
*
* ... what the bananas, Unity
*/
private static GUIStyle openFoldoutStyle;
private static GUIStyle closedFoldoutStyle;
private static bool initted;
private static void Init() {
openFoldoutStyle = new GUIStyle( GUI.skin.FindStyle("Foldout") );
openFoldoutStyle.fontStyle = (FontStyle)1;
openFoldoutStyle.stretchHeight = true;
closedFoldoutStyle = new GUIStyle( openFoldoutStyle );
openFoldoutStyle.normal = openFoldoutStyle.onNormal;
openFoldoutStyle.active = openFoldoutStyle.onActive;
initted = true;
}
public static bool Foldout(bool open, string text ) { return Foldout(open, new GUIContent(text)); }
public static bool Foldout(bool open, GUIContent text ) {
if ( !initted ) Init();
if ( open ) {
if ( GUILayout.Button( text, openFoldoutStyle, GUILayout.Height(20) ) ) {
GUI.FocusControl ("");
GUI.changed = false; // force change-checking group to take notice
GUI.changed = true;
return false;
}
} else {
if ( GUILayout.Button( text, closedFoldoutStyle, GUILayout.Height(20) ) ) {
GUI.FocusControl ("");
GUI.changed = false; // force change-checking to take notice
GUI.changed = true;
return true;
}
}
return open;
}
}
...
sectionOpen = GUIUtils.Foldout( sectionOpen, "Section Title");
This also brings me on the right path but i'm gonna try to edit this code to look more like the particle system one. When i'm done with it ill post it here.