Unity new UI - Динамічно змінюйте функції, викликані елементами графічного інтерфейсу


17

Потрібно динамічно змінити значення за допомогою кнопки OnClick та повзунка On Value Changed приклад 1 приклад 2.

Якщо мені довелося здогадатися, як це робиться, знайдіть посилання на елемент кнопки / gui. Далі отримайте компонент сценарію кнопки та перейдіть до цього списку викликів функцій. Однак я не впевнений, як змінити цей список. У когось є якісь ідеї?

Детальніше, що може допомогти:

  • Викликана функція є окремим компонентом сценарію
  • Використання опції "динамічна" змінна для повзунків
  • Може використовуватися для створення динамічних кнопок

Відповіді:


23

Є надзвичайно простий спосіб змінити події:

EDIT

Дивіться іншу відповідь про швидкий і простий спосіб додати подію лише до 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.