Como crio um botão de alternância no Unity Inspector?

13

Quero criar uma ferramenta semelhante à ferramenta Terreno do Unity, que possui alguns botões de alternância no inspetor:

Botões de alternância no inspetor Botão alternado

Como posso obter um design semelhante a isso? Sei como criar botões normais e outros componentes da interface do usuário no inspetor, mas não consigo encontrar informações suficientes para alternar os botões.

Até agora, usei alternadores normais que produzem uma caixa de seleção:

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;
}

Definir a alternância GUIStylepara "Botão" não produz o resultado desejado. O conteúdo do texto ou da imagem fica à esquerda do botão em vez de dentro.

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

Comportamento indesejado ao alternar

Além disso, nenhuma das opções encontradas no GUISkin parece não ajudar.

Lasse
fonte

Respostas:

8

Resolvi esse problema usando os botões em vez de alternar.

Primeiro defina dois estilos de botão antes de qualquer função:

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

Em seguida, OnInspectorGui()verifique se eles são gerados se nulos:

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

E então use a idéia proposta por @jzx para alternar entre os 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();

Isso produz o que eu queria:

Primeiro botão alternado Segundo botão alternado

Lasse
fonte
1
Bom trabalho! Eu estava procurando por dias para encontrar a resposta para os botões de alternância no Unity3D Editor. Apenas uma pergunta - por que você simplesmente não usa _smoothValue = !GUILayout.Button( SetAmountFieldContent, _smoothValue ? ToggleButtonStyleToggled : ToggleButtonStyleNormal), em vez de ter dois booleanos? Isso funciona bem para mim e o código parece próximo ao uso do botão / alternância padrão da unidade
Ivaylo Slavov
1
@IvayloSlavov eu usei isso como um exemplo para maior clareza
Lasse
4

Alternar retorna o estado atual do botão - o mesmo estado passado no valor ou o novo valor alterado pelo usuário. Então, um padrão melhor seria ...

// 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.
}

Você pode usar o mesmo padrão de troca dependente do 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
fonte
2

Aqui está uma maneira básica, mas simples de fazer isso:

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

tirado daqui

Kari
fonte
2

Use GUILayout.Toolbar . Os documentos são enganosos, na verdade, eles funcionam juntos:

exemplo da barra de ferramentas

Além disso, você pode usar os estilos "buttonleft", "buttonmid", "buttonright" para desenhar diretamente esse estilo de botão.

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

Você consegue fazer isso:

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
    }
}

É muito importante que você instancia buttonStyledentro, OnInspectorGUI()caso contrário você receberá um erro. Além disso, não faça isso, buttonStyle = GUI.skin.button;porque você copiaria a skin.buttonreferência e qualquer alteração alteraria buttonStyletodos os estilos de botões.

Hyago Oliveira
fonte