¿Cómo creo un botón de alternar en Unity Inspector?

13

Quiero crear una herramienta similar a la herramienta Terreno de Unity, que tiene algunos botones de alternancia agradables en el inspector:

Alternar botones en el inspector Botón de alternancia

¿Cómo puedo lograr un diseño similar a este? Sé cómo crear botones normales y otros componentes de la interfaz de usuario en el inspector, pero no puedo encontrar suficiente información para activar o desactivar los botones.

Hasta ahora he usado conmutadores normales que producen una casilla de verificación:

var tmp = EditorGUILayout.Toggle( SetAmountFieldContent, _setValue );

if ( tmp != _setValue )
{
  _setValue = tmp;
  if ( _setValue )
    _smoothValue = false;
}

tmp = EditorGUILayout.Toggle( SmoothValueFieldContent, _smoothValue );

if ( tmp != _smoothValue )
{
  _smoothValue = tmp;
  if ( _smoothValue )
    _setValue = false;
}

Establecer la palanca GUIStyleen "Botón" no produce el resultado deseado. El contenido del texto o la imagen va a la izquierda del botón en lugar de adentro.

var tmp = EditorGUILayout.Toggle( SetAmountFieldContent, _setValue, "Button" );

Comportamiento no deseado en alternar

Además, ninguna de las opciones encontradas en GUISkin no parece ayudar.

Lasse
fuente

Respuestas:

8

Resolví este problema usando botones en lugar de alternar.

Primero defina dos estilos de botones antes de cualquier función:

private static GUIStyle ToggleButtonStyleNormal = null;
private static GUIStyle ToggleButtonStyleToggled = null;

Luego, OnInspectorGui()asegúrese de que se generen si son nulos:

if ( ToggleButtonStyleNormal == null )
{
  ToggleButtonStyleNormal = "Button";
  ToggleButtonStyleToggled = new GUIStyle(ToggleButtonStyleNormal);
  ToggleButtonStyleToggled.normal.background = ToggleButtonStyleToggled.active.background;
}

Y luego use la idea propuesta por @jzx para alternar los estilos:

GUILayout.BeginHorizontal(  );

if ( GUILayout.Button( SetAmountFieldContent, _setValue ? ToggleButtonStyleToggled : ToggleButtonStyleNormal ) )
{
  _setValue = true;
  _smoothValue = false;
}

if ( GUILayout.Button( SmoothValueFieldContent, _smoothValue ? ToggleButtonStyleToggled : ToggleButtonStyleNormal ) )
{
  _smoothValue = true;
  _setValue = false;
}

GUILayout.EndHorizontal();

Esto produce lo que quería:

Primer botón activado Segundo botón activado

Lasse
fuente
1
¡Gran trabajo! Estuve buscando días para encontrar la respuesta para los botones de alternar en el Editor de Unity3D. Solo una pregunta: ¿por qué no lo usas en _smoothValue = !GUILayout.Button( SetAmountFieldContent, _smoothValue ? ToggleButtonStyleToggled : ToggleButtonStyleNormal)lugar de tener dos booleanos? Eso funciona bien para mí y el código parece estar cerca de usar el botón / alternar de la unidad estándar
Ivaylo Slavov
1
@IvayloSlavov Lo usé como un ejemplo de claridad
Lasse el
4

Toggle devuelve el estado actual del botón, ya sea el mismo estado pasado en valor o el nuevo valor modificado por el usuario. Entonces un mejor patrón sería ...

// TODO: Initialize these with GUIContent
private GUIContent _toggleButtonDepressedLabel;
private GUIContent _toggleButtonDefaultLabel;

// Current toggle state
bool _toggleButtonState;

void DisplayToggle()
{
    var image = _toggleButtonValue
                ? _toggleButtonDepressedLabel
                : _toggleButtonDefaultLabel;
    var newState = EditorGUILayout.Toggle(image, _toggleButtonState);
    if (newState != _toggleButtonState)
    {
        _toggleButtonState = newState;
        OnToggleButtonChanged();
    }
}

void OnGUI ()
{
    DisplayToggle();
}

void OnToggleButtonChanged()
{
    // Do stuff.
}

Puede usar el mismo patrón de intercambio dependiente del estado para GUIStyles.

private GUIStyle _toggleButtonDepressedStyle;
private GUIStyle _toggleButtonDefaultStyle;
// ...
    var image = _toggleButtonValue
                ? _toggleButtonDepressedLabel
                : _toggleButtonDefaultLabel;
    var style = _toggleButtonValue
                ? _toggleButtonDepressedStyle
                : _toggleButtonDefaultStyle;
    var newState = EditorGUILayout.Toggle(image, _toggleButtonState, style);
jzx
fuente
3

Aquí hay una forma básica pero simple de hacerlo:

 pressed = GUILayout.Toggle(pressed, "Toggle me !", "Button");

tomado de aquí

Kari
fuente
1
Esta es una manera bastante simple de hacer esto.
nsxdavid
2

Utilice GUILayout.Toolbar . Los documentos son engañosos, en realidad ejecuta los botones juntos:

ejemplo de barra de herramientas

Además, puede usar los estilos "buttonleft", "buttonmid", "buttonright" para dibujar directamente este estilo de botón.

        var left = GUI.skin.FindStyle("buttonleft");
        GUILayout.Button("left only button", left);
BorisTheBrave
fuente
0

Puedes hacerlo:

private GUIStyle buttonStyle;
private bool enableToogle;

public override void OnInspectorGUI()
{
    buttonStyle = new GUIStyle(GUI.skin.button);
    enableToogle = GUILayout.Toggle(enableToogle, "Toogle Me", buttonStyle);

    if(enableToogle)
    {
        // your stuff here
    }
}

Es muy importante que instancias buttonStyledentro, de lo OnInspectorGUI()contrario obtendrás un error. Además, no lo haga buttonStyle = GUI.skin.button;porque estaría copiando la skin.buttonreferencia y cualquier cambio en buttonStyleestaría cambiando todos los estilos de botones.

Hyago Oliveira
fuente