Nueva interfaz de usuario de Unity: cambie dinámicamente las funciones llamadas por elementos GUI

17

Buscando cambiar dinámicamente el valor en el botón OnClick y el control deslizante On Value Changed Ejemplo 1 ejemplo 2.

Si tuviera que adivinar cómo se hizo esto, obtenga una referencia al elemento botón / gui. A continuación, obtenga el componente de script Button y acceda a esa lista de llamadas a funciones. Sin embargo, no estoy seguro de cómo modificar esa lista. ¿Alguien tiene alguna idea?

Más detalles que pueden ayudar:

  • La función que se llama es aparte de un componente de script personalizado
  • Uso de la opción variable 'dinámica' para los controles deslizantes
  • Podría usarse para crear botones dinámicos
la mantequilla mortal
fuente

Respuestas:

23

Hay una forma súper simple de cambiar eventos:

EDITAR

Vea mi otra respuesta para la forma rápida y fácil de agregar un evento solo para el OnClickevento. Para otros eventos, como OnDragver a continuación.


Además, si necesita algo más que los eventos proporcionados de forma predeterminada, sugeriría adjuntar un EventTriggerobjeto a su juego. Esto nos da acceso al BaseEventDataobjeto devuelto por el evento y nos dice cosas como el objeto que creó el evento. Entonces puedes hacer algo como:

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

Entonces podemos crear un método para manejar eventos, la firma debe coincidir con la de nuestro delegado. Por lo tanto, debe regresar voidy aceptar BaseEventDatacomo su primer y único parámetro:

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

Finalmente, para agregar dinámicamente el 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);

Si está utilizando la versión 5.3.3 o superior, use esta línea en lugar de la última línea anterior, delegados se deprecia :

eventTrigger.triggers.Add(entry); 
MichaelHouse
fuente
Parece que cuando agrega dinámicamente un controlador, no parece aparecer en el inspector. Drawer todavía muestra "Lista vacía" para los delegados
vexe
Eso es correcto. Los controladores agregados desde el código están separados de los controladores "persistentes" que se muestran en el inspector; además, usted es responsable de limpiar estos controladores (a diferencia de los persistentes, que Unity se encarga de usted).
Joe Strout
11

La palabra es que la delegate{}sintaxis encontrada en mi respuesta anterior es obsoleta, hay otra forma de hacerlo usando la notación 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!");
}

O puede pasar el botón para hacer las cosas un poco más dinámicas:

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!");
}
MichaelHouse
fuente
Tenga en cuenta que esta estrategia es solo para el OnClickevento. Para agregar dinámicamente otros eventos, debe seguir las instrucciones en mi otra respuesta.
MichaelHouse
0

Cree un nuevo script, en la línea de:

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

Este script se implementa en la interfaz IPointerClickHandler (entre muchas otras interfaces disponibles ). Simplemente adjuntar este script a un elemento de la interfaz de usuario permitirá que este script intercepte eventos de clic (o cualquier evento para el que implemente la interfaz).

El siguiente paso es simplemente agregar dinámicamente este script como componente al elemento de la interfaz de usuario que desee:

myButton.AddComponent<EventHandler>();

Esto agregará el script como componente myButtony la próxima vez que haga clic en el botón, obtendré información sobre qué botón se hizo clic y dónde se realizó el clic.

Esto proporciona la mayor información sobre el evento en comparación con mis otras respuestas.

MichaelHouse
fuente
0

La forma en que la unidad implementa la interfaz de usuario es como cualquier otro componente de la unidad. Agrega GameObject y le agrega componentes de la interfaz de usuario. Una vez que tenga el objeto del juego, puede obtener los componentes de la interfaz de usuario y cambiar las propiedades.

La referencia de API para UI se puede encontrar en el espacio de nombres UnityEngine.UI, la referencia de API para BUtton es http://docs.unity3d.com/ScriptReference/UI.Button.html

Consulte la publicación http://blog.trsquarelab.com/2015/03/new-ui-implementation-using-c-scripts.html para obtener más información sobre cómo acceder a la interfaz de usuario desde los scripts de C #

Ranjith
fuente