Nouvelle interface utilisateur Unity - Modifier dynamiquement les fonctions appelées par les éléments GUI

17

Vous cherchez à modifier dynamiquement la valeur dans le bouton OnClick et le curseur On Value Changed Exemple 1 exemple 2.

Si je devais deviner comment cela a été fait, obtenez une référence à l'élément button / gui. Obtenez ensuite le composant de script Button et accédez à cette liste d'appels de fonction. Cependant, je ne sais pas comment modifier cette liste. Quelqu'un a des idées?

Plus de détails qui pourraient aider:

  • La fonction appelée est en dehors d'un composant de script personnalisé
  • Utilisation de l'option de variable «dynamique» pour les curseurs
  • Pourrait être utilisé pour créer des boutons dynamiques
le beurre
la source

Réponses:

23

Il existe un moyen super simple de modifier les événements:

ÉDITER

Voir mon autre réponse pour le moyen rapide et facile d'ajouter un événement pour l' OnClickévénement uniquement. Pour d'autres événements, comme OnDragci-dessous.


De plus, si vous avez besoin de plus que les événements fournis par défaut, je vous suggère plutôt de joindre un EventTriggerà votre objet de jeu. Cela nous donne accès à l' BaseEventDataobjet renvoyé de l'événement, nous indiquant des choses comme l'objet qui a créé l'événement. Ensuite, vous pouvez faire quelque chose comme:

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

Ensuite, nous pouvons créer une méthode pour gérer les événements, la signature doit correspondre à celle de notre délégué. Il doit donc retourner voidet accepter BaseEventDatacomme premier et seul paramètre:

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

Enfin, pour ajouter dynamiquement l'événement:

//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 vous utilisez la version 5.3.3 ou supérieure, utilisez cette ligne à la place de la dernière ligne ci-dessus, les délégués sont dépréciés :

eventTrigger.triggers.Add(entry); 
MichaelHouse
la source
Il semble que lorsque vous ajoutez dynamiquement un gestionnaire, il ne semble pas apparaître dans l'inspecteur. Le tiroir affiche toujours "Liste vide" pour les délégués
vexe
C'est correct. Les gestionnaires ajoutés à partir du code sont distincts des gestionnaires "persistants" affichés dans l'inspecteur; de plus, vous êtes responsable du nettoyage de ces gestionnaires (contrairement aux persistants dont Unity s'occupe pour vous).
Joe Strout
11

Le mot est que la delegate{}syntaxe trouvée dans ma réponse précédente est obsolète, il existe une autre façon de le faire en utilisant la notation 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!");
}

Ou vous pouvez passer le bouton pour rendre les choses un peu plus dynamiques:

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
la source
Gardez à l'esprit, cette stratégie est uniquement pour l' OnClickévénement. Afin d'ajouter dynamiquement d'autres événements, vous devez suivre les instructions de mon autre réponse.
MichaelHouse
0

Créez un nouveau script, sur le modèle de:

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

Ce script implémente dans l'interface IPointerClickHandler (parmi de nombreuses autres interfaces disponibles ). Le simple attachement de ce script à un élément d'interface utilisateur permettra à ce script d'intercepter les événements de clic (ou tout événement pour lequel vous implémentez l'interface).

L'étape suivante consiste à simplement ajouter dynamiquement ce script en tant que composant à l'élément d'interface utilisateur que vous souhaitez:

myButton.AddComponent<EventHandler>();

Cela ajoutera le script en tant que composant myButtonet la prochaine fois que je cliquera sur le bouton, j'obtiendrai des informations sur le bouton sur lequel vous avez cliqué et sur l'endroit où le clic a eu lieu.

Cela fournit le plus d'informations sur l'événement par rapport à mes autres réponses.

MichaelHouse
la source
0

La façon dont l'unité implémente l'interface utilisateur est comme tout autre composant d'unité. Vous ajoutez GameObject et y attachez des composants d'interface utilisateur. Une fois que vous avez l'objet de jeu, vous pouvez en obtenir les composants d'interface utilisateur et modifier les propriétés.

La référence API pour l'interface utilisateur se trouve sous l'espace de noms UnityEngine.UI, la référence API pour BUtton est http://docs.unity3d.com/ScriptReference/UI.Button.html

Voir l'article http://blog.trsquarelab.com/2015/03/new-ui-implementation-using-c-scripts.html pour plus d'informations sur l'accès à l'interface utilisateur à partir de scripts C #

Ranjith
la source