Jak utworzyć przycisk przełączania w Unity Inspector?

13

Chcę stworzyć narzędzie podobne do narzędzia terenu Unity, które ma kilka fajnych przycisków przełączania w inspektorze:

Przełącz przyciski w inspektorze Przycisk przełączany

Jak mogę uzyskać podobny projekt do tego? Wiem, jak tworzyć normalne przyciski i inne komponenty interfejsu w inspektorze, ale nie mogę znaleźć wystarczającej ilości informacji, aby przełączać przyciski.

Do tej pory używałem normalnych przełączników, które generują pole wyboru:

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

Ustawienie przełącznika GUIStylena „Przycisk” nie daje pożądanego rezultatu. Treść tekstu lub obrazu znajduje się po lewej stronie przycisku zamiast w środku.

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

Niepożądane zachowanie przy przełączaniu

Również żadna z opcji znalezionych w GUISkin nie wydaje się pomóc.

Lasse
źródło

Odpowiedzi:

8

Rozwiązałem ten problem, używając przycisków zamiast przełączników.

Najpierw zdefiniuj dwa style przycisków przed dowolnymi funkcjami:

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

Następnie OnInspectorGui()upewnij się, że są generowane, jeśli null:

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

A następnie skorzystaj z pomysłu zaproponowanego przez @jzx, aby przełączyć style:

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();

To daje to, czego chciałem:

Pierwszy przycisk przełączany Drugi przycisk przełączany

Lasse
źródło
1
Dobra robota! Szukałem dni, aby znaleźć odpowiedź na przełączniki w edytorze Unity3D. Tylko jedno pytanie - dlaczego po prostu nie użyjesz _smoothValue = !GUILayout.Button( SetAmountFieldContent, _smoothValue ? ToggleButtonStyleToggled : ToggleButtonStyleNormal)zamiast dwóch booleanów? Działa to dla mnie dobrze, a kod wygląda na to, że używam przycisku / przełączników Stadnard Unity
Ivaylo Slavov
1
@IvayloSlavov Użyłem tego jako przykładu dla jasności
Lasse
4

Toggle zwraca bieżący stan przycisku - albo ten sam stan przekazany w wartości, albo nową wartość zmienioną przez użytkownika. Lepszym wzorem byłby więc ...

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

Możesz użyć tego samego wzorca wymiany zależnego od stanu dla 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
źródło
3

Oto prosty, ale prosty sposób:

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

zabrane stąd

Kari
źródło
1
Jest to dość prosty sposób na zrobienie tego.
nsxdavid
2

Użyj GUILayout.Toolbar . Dokumenty wprowadzają w błąd, w rzeczywistości uruchamiają przyciski razem:

przykład paska narzędzi

Dodatkowo możesz użyć stylów „buttonleft”, „buttonmid”, „buttonright”, aby narysować te style przycisków bezpośrednio.

        var left = GUI.skin.FindStyle("buttonleft");
        GUILayout.Button("left only button", left);
BorisTheBrave
źródło
0

Możesz to zrobić:

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

Bardzo ważne jest, abyś włączył się do buttonStyleśrodka, w OnInspectorGUI()przeciwnym razie wystąpi błąd. Nie rób też tego, buttonStyle = GUI.skin.button;ponieważ kopiujesz skin.buttonodwołanie, a każda zmiana buttonStylespowoduje zmianę wszystkich stylów przycisków.

Hyago Oliveira
źródło