Unity new UI - динамически изменяйте функции, вызываемые элементами GUI


17

Нужно динамически менять значение в кнопке OnClick и в ползунке On Value Changed пример 1 пример 2.

Если бы мне пришлось угадывать, как это было сделано, получите ссылку на элемент button / gui. Затем получите компонент скрипта Button и получите доступ к этому списку вызовов функций. Однако я не уверен, как изменить этот список. У кого-нибудь есть идеи?

Более подробная информация, которая может помочь:

  • Вызываемая функция является частью отдельного компонента скрипта
  • Использование параметра динамической переменной для ползунков
  • Может быть использован для создания динамических кнопок

Ответы:


23

Есть супер простой способ изменить события:

РЕДАКТИРОВАТЬ

Смотрите мой другой ответ для быстрого и простого способа добавить событие только для OnClickсобытия. Для других событий, как OnDragсм. Ниже.


Кроме того, если вам нужно больше, чем просто события, предоставляемые по умолчанию, я бы предложил вместо этого присоединить объект EventTriggerк вашему игровому объекту. Это дает нам доступ к BaseEventDataобъекту, возвращенному из события, сообщая нам такие вещи, как объект, который создал событие. Тогда вы можете сделать что-то вроде:

//Create an event delegate that will be used for creating methods that respond to events
public delegate void EventDelegate(UnityEngine.EventSystems.BaseEventData baseEvent);

Затем мы можем создать метод для обработки событий, подпись должна соответствовать подписи нашего делегата. Таким образом, он должен вернуть voidи принять в BaseEventDataкачестве своего первого и единственного параметра:

public void DropEventMethod(UnityEngine.EventSystems.BaseEventData baseEvent) {
    Debug.Log(baseEvent.selectedObject.name + " triggered an event!");
    //baseEvent.selectedObject is the GameObject that triggered the event,
    // so we can access its components, destroy it, or do whatever.
}

Наконец, чтобы динамически добавить событие:

//Get the event trigger attached to the UI object
EventTrigger eventTrigger = buttonObject.GetComponent<EventTrigger>();

//Create a new entry. This entry will describe the kind of event we're looking for
// and how to respond to it
EventTrigger.Entry entry = new EventTrigger.Entry();

//This event will respond to a drop event
entry.eventID = EventTriggerType.Drop;

//Create a new trigger to hold our callback methods
entry.callback = new EventTrigger.TriggerEvent();

//Create a new UnityAction, it contains our DropEventMethod delegate to respond to events
UnityEngine.Events.UnityAction<BaseEventData> callback =
    new UnityEngine.Events.UnityAction<BaseEventData>(DropEventMethod);

//Add our callback to the listeners
entry.callback.AddListener(callback);

//Add the EventTrigger entry to the event trigger component
eventTrigger.delegates.Add(entry);

Если вы используете версию 5.3.3 или выше, используйте эту строку вместо последней строки выше, делегаты не рекомендуются :

eventTrigger.triggers.Add(entry); 

Кажется, что когда вы динамически добавляете обработчик, он не появляется в инспекторе. Ящик по-прежнему показывает «Пустой список» для делегатов
vexe

Правильно. Обработчики, добавленные из кода, отделены от «постоянных» обработчиков, показанных в инспекторе; кроме того, вы несете ответственность за очистку этих обработчиков (в отличие от постоянных, которые Unity заботится о вас).
Джо Струт

11

Слово в том, что delegate{}синтаксис, найденный в моем предыдущем ответе, устарел, есть другой способ сделать это с помощью лямбда-нотации:

void buttonSetup(Button button) {
    //Remove the existing events
    button.onClick.RemoveAllListeners();
    //Add your new event using lambda notation
    button.onClick.AddListener (handleButton);
}

void handleButton() {
    Debug.Log("Button pressed!");
}

Или вы можете передать кнопку, чтобы сделать вещи немного более динамичными:

void buttonSetup(Button button) {
    button.onClick.RemoveAllListeners();
    //Add your new event
    button.onClick.AddListener(() => handleButton(button));
}

void handleButton(Button b) {
    Debug.Log("Button '" + b.name + "' pressed!");
}

Имейте в виду, эта стратегия только для OnClickмероприятия. Для того, чтобы динамически добавлять другие события, вы должны следовать инструкциям в моем другом ответе.
MichaelHouse

0

Создайте новый скрипт в соответствии с:

public class EventHandler : MonoBehaviour, IPointerClickHandler
{
    public void OnPointerClick(PointerEventData eventData)
    {
        Debug.Log("Element: " +
                   eventData.selectedObject.name +
                   " was clicked at " +
                   eventData.position.ToString());
    }
}

Этот скрипт реализует в интерфейсе IPointerClickHandler (среди многих других доступных интерфейсов ). Простое присоединение этого сценария к элементу пользовательского интерфейса позволит этому сценарию перехватывать события щелчка (или любое другое событие, для которого вы реализуете интерфейс).

Следующий шаг - просто динамически добавить этот скрипт в качестве компонента к нужному элементу пользовательского интерфейса:

myButton.AddComponent<EventHandler>();

Это добавит скрипт в качестве компонента, myButtonи в следующий раз, когда я нажму кнопку, я получу информацию о том, какая кнопка была нажата и где произошел щелчок.

Это дает больше информации о событии по сравнению с другими моими ответами.


0

То, как единство реализует пользовательский интерфейс, точно так же, как и любые другие компоненты единства. Вы добавляете GameObject и присоединяете к нему компоненты пользовательского интерфейса. Если у вас есть игровой объект, вы можете получить из него компоненты пользовательского интерфейса и изменить свойства.

Ссылку API для пользовательского интерфейса можно найти в пространстве имен UnityEngine.UI, ссылку API для BUtton - http://docs.unity3d.com/ScriptReference/UI.Button.html.

См. Пост http://blog.trsquarelab.com/2015/03/new-ui-implementation-using-c-scripts.html для получения дополнительной информации о доступе к пользовательскому интерфейсу из сценариев C #

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.