Nuova interfaccia utente di Unity: modifica dinamica delle funzioni chiamate dagli elementi della GUI


17

Cercando di modificare dinamicamente il valore nel pulsante OnClick e nel cursore On Value Changed Esempio 1 esempio 2.

Se dovessi indovinare come è stato fatto, ottenere un riferimento all'elemento button / gui. Quindi ottenere il componente Script pulsante e accedere a tale elenco di chiamate di funzione. Tuttavia non sono sicuro di come modificare tale elenco. Qualcuno ha qualche idea?

Maggiori dettagli che potrebbero aiutare:

  • La funzione chiamata è parte di un componente di script personalizzato
  • Utilizzo dell'opzione variabile 'dinamica' per i cursori
  • Potrebbe essere usato per creare pulsanti dinamici

Risposte:


23

C'è un modo super semplice per cambiare gli eventi:

MODIFICARE

Vedi la mia altra risposta per il modo semplice e veloce di aggiungere un evento solo per l' OnClickevento. Per altri eventi, come OnDragvedi sotto.


Inoltre, se hai bisogno di qualcosa di più degli eventi forniti per impostazione predefinita, suggerirei invece di allegare un EventTriggeroggetto di gioco. Questo ci dà accesso BaseEventDataall'oggetto restituito dall'evento, raccontandoci cose come l'oggetto che ha creato l'evento. Quindi puoi fare qualcosa del tipo:

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

Quindi possiamo creare un metodo per gestire gli eventi, la firma deve corrispondere a quella del nostro delegato. Quindi, deve restituire voide accettare BaseEventDatacome primo e unico parametro:

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

Infine, per aggiungere dinamicamente l'evento:

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

Se si utilizza la versione 5.3.3 o successiva, utilizzare questa riga anziché l'ultima riga precedente, i delegati sono ammortizzati :

eventTrigger.triggers.Add(entry); 

Sembra che quando si aggiunge dinamicamente un gestore non sembra apparire nell'ispettore. Il cassetto mostra ancora "Elenco vuoto" per i delegati
vexe

È corretto. I gestori aggiunti dal codice sono separati dai gestori "persistenti" mostrati nella finestra di ispezione; inoltre, sei responsabile della pulizia di questi gestori (a differenza di quelli persistenti, di cui Unity si occupa).
Joe Strout,

11

La parola è che la delegate{}sintassi trovata nella mia risposta precedente è obsoleta, c'è un altro modo di farlo usando la notazione lambda:

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!");
}

Oppure puoi passare il pulsante per rendere le cose un po 'più dinamiche:

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!");
}

Tieni presente che questa strategia è solo per l' OnClickevento. Per aggiungere dinamicamente altri eventi, devi seguire le istruzioni nella mia altra risposta.
MichaelHouse

0

Crea un nuovo script, seguendo le linee di:

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

Questo script implementa nell'interfaccia IPointerClickHandler (tra molte altre interfacce disponibili ). Il semplice collegamento di questo script a un elemento dell'interfaccia utente consentirà a questo script di intercettare gli eventi clic (o qualsiasi evento per cui si implementa l'interfaccia).

Il prossimo passo è semplicemente aggiungere dinamicamente questo script come componente all'elemento UI che desideri:

myButton.AddComponent<EventHandler>();

Questo aggiungerà lo script come componente a myButton e la prossima volta che farò clic sul pulsante, otterrò informazioni su quale pulsante è stato fatto clic e su dove ha avuto luogo il clic.

Ciò fornisce la maggior parte delle informazioni sull'evento rispetto alle altre mie risposte.


0

Come l'unità implementa l'interfaccia utente è proprio come qualsiasi altra componente di unità. Aggiungete GameObject e vi collegate i componenti dell'interfaccia utente. Una volta che hai l'oggetto di gioco, puoi ottenere i componenti dell'interfaccia utente e modificarne le proprietà.

Il riferimento API per l'interfaccia utente è disponibile nello spazio dei nomi UnityEngine.UI, il riferimento API per BUtton è http://docs.unity3d.com/ScriptReference/UI.Button.html

Vedere il post http://blog.trsquarelab.com/2015/03/new-ui-implementation-using-c-scripts.html per ulteriori informazioni sull'accesso all'interfaccia utente dagli script C #

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.