Как заставить работать невидимую прозрачную кнопку?

Глядя на некоторые ответы на форумах Unity и на сайте вопросов и ответов, ответы о том, как сделать невидимую кнопку, не работают, потому что удаление изображения, связанного с кнопкой, приводит к тому, что оно не работает.

Как обойти это и сохранить невидимое свойство, позволяя кнопке фактически работать?

2 ответа

Решение

Это одна из тех странных вещей об Unity...

Это нужно 100% реальных проектов, но Unity забыла это сделать.

Укороченная версия:

Вам нужен Touchable.cs в каждом проекте Unity:

// file Touchable.cs
// Correctly backfills the missing Touchable concept in Unity.UI's OO chain.

using UnityEngine;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
[CustomEditor(typeof(Touchable))]
public class Touchable_Editor : Editor
     { public override void OnInspectorGUI(){} }
#endif
public class Touchable:Text
     { protected override void Awake() { base.Awake();} }
  1. Используйте обычную функцию редактора Unity " Create Button"

  2. Как вы знаете, функция редактора автоматически добавляет для вас два компонента. Один Text и один Image...

  3. Просто удалите их обоих

  4. Удалите вышеуказанный скрипт Touchable.cs на кнопке

Вы сделали. Это все, что нужно сделать.

Он не может "распасться" с обновлениями Unity.

Вы можете фактически "застегнуть" что-нибудь в .UI сбросив Touchable на нем.

Никогда больше "добавить прозрачное изображение", чтобы сделать кнопку.


Unity забыла абстрагировать "осязаемую" концепцию в цепочке OO.

Поэтому нам, разработчикам, приходится создавать собственный класс Touchable "из" классов Unity.

Это классическая проблема "обратной засыпки" в ОО.

При "обратной засыпке" единственной проблемой является то, что она должна быть полностью автоматически поддерживаемой. Есть только одно хорошее решение, Touchable.cs, которым пользуются все.


Таким образом, во всех реальных проектах Unity кнопка выглядит так:

ОДИН У вас есть Unity's Button.cs

ВТОРОЙ вы должны добавить Touchable.cs

Некоторые команды создают функцию редактора "Создать лучшую кнопку", которая просто создает игровой объект с помощью кнопок Button.cs + Touchable.cs.

Важный совет...

Скажем, у вас может быть очень сложная панель интерфейса. Может быть, это изменяет размер. Или, может быть, у вас есть анимация.

Удивительно то, что вы можете просто вставить "Button+Touchable" на что-нибудь подобное, и это будет работать.

Просто установите Button + Touchable, чтобы развернуть, чтобы заполнить родительский элемент. Это все, что нужно сделать.

В этом примере изображения "resume" и "quit" могут быть чем угодно. (Анимация, сложная панель со многими частями, текстом, спрайтами, невидимым, стеком - чем угодно.)

Во всех случаях просто поместите кнопку + Touchable внизу, и у вас есть безупречная кнопка.

На самом деле: этот подход настолько прост, что вы сделаете даже самые простые кнопки, используя этот подход.

Скажите, что ваша кнопка - тривиальное изображение. Гораздо проще просто иметь изображение, а затем добавить на него кнопку + Touchable. (Вместо того, чтобы использовать действительно запутанную и проблематичную функцию "Кнопка" в редакторе.)

Понимание ситуации...

1) Единство Button.cs класс фантастический.

2) Но функция редактора "сделать кнопку" - это мусор...

3) Это делает кнопку "вверх ногами",

4) т.е. он помещает текст / изображение в Button.cs

5) "Button-ness" - это то, что вы должны добавить ко всему. Именно так и работает с Button + Touchable.

6) Так что - довольно просто -

1. Есть все, что вы хотите. Текст, изображение, панель, невидимка, анимация - что угодно.

2. Drop Button + Touchable на нем - все готово.

Вот так все делают все кнопки в Unity!


Историческая заслуга: я считаю, что пользователь Unity на форуме "signalZak" был первым, кто об этом подумал много, много лет назад!

В качестве возможного улучшения ответа Фатти, изменив Touchableбазовый класс для Graphic и преобладающий protected void UpdateGeometry() кажется, работает довольно хорошо с белым, уменьшая (по общему признанию незначительные) накладные расходы, связанные с Text.

public class Touchable:Graphic
{
    protected override void UpdateGeometry() { }
}

Я запустил GIMP (бесплатный графический инструмент для кодирования). Создано новое изображение (любого размера, я выбрал 10 x 10 пикселей), выбранное из расширенных (в диалоговом окне создания), что его фон должен быть прозрачным. Сохранил файл. Экспортировал его как png с выбранным цветом фона для сохранения. Перетащил в Unity как спрайт. Поместите это в изображение кнопки. Отключена текстовая составляющая кнопки. Код не требуется... просто не рисуйте ничего в GIMP (это было самое сложное).

Моим первым решением было enable а также disable компоненты, как показано ниже:

void showButton(Button buttonToShow, bool show)
{
    Image bImage = buttonToShow.GetComponent<Image>();
    Text bText = buttonToShow.GetComponentInChildren<Text>(); //Text is a child of the Button

    if (bImage != null)
    {
        bImage.enabled = show;
    }

    if (bText != null)
    {
        bText.enabled = show;
    }
}

но это не сработало. Если кнопка image а также text оба компонентаdisabled, событие нажатия кнопки НЕ сработает. Один из них ДОЛЖЕН быть enabled в состоянии клик для событий, которые будут отправлены.

Решение состоит в том, чтобы установить альфа как image а также text компоненты до 0, чтобы скрыть и до 1, чтобы показать снова. Они будут скрыты, но не отключены и нажмите events буду работать.

public Button button;

void Start()
{
    //Show Button
    showButton(button, true);

    //Hide Button
    //showButton(button, false);
}

void showButton(Button buttonToShow, bool show)
{
    Image bImage = buttonToShow.GetComponent<Image>();
    Text bText = buttonToShow.GetComponentInChildren<Text>(); //Text is a child of the Button

    if (bImage != null)
    {
        Color tempColor = bImage.color;

        if (show)
        {
            tempColor.a = 1f; //Show 
            bImage.color = tempColor;
        }
        else
        {
            tempColor.a = 0f; //Hide 
            bImage.color = tempColor;

        }
    }

    if (bText != null)
    {
        Color tempColor = bText.color;

        if (show)
        {
            tempColor.a = 1f; //Show 
            bText.color = tempColor;
        }
        else
        {
            tempColor.a = 0f; //Hide 
            bText.color = tempColor;

        }
    }
}
Другие вопросы по тегам