Unity new UI - Altere dinamicamente as funções chamadas pelos elementos da GUI

17

Procurando alterar dinamicamente o valor no botão OnClick e o controle deslizante On Value Changed Exemplo 1 exemplo 2.

Se eu tivesse que adivinhar como isso foi feito, consulte o elemento button / gui. Em seguida, obtenha o componente de script Button e acesse essa lista de chamadas de função. No entanto, não tenho certeza de como modificar essa lista. Alguém tem alguma ideia?

Mais detalhes que podem ajudar:

  • A função que está sendo chamada faz parte de um componente de script personalizado
  • Usando a opção variável 'dinâmica' para os controles deslizantes
  • Pode ser usado para criar botões dinâmicos
thedeadlybutter
fonte

Respostas:

23

Existe uma maneira super simples de alterar eventos:

EDITAR

Veja minha outra resposta para a maneira rápida e fácil de adicionar um evento apenas para o OnClickevento. Para outros eventos, como OnDragveja abaixo.


Além disso, se você precisar de mais do que apenas os eventos fornecidos por padrão, sugiro anexar um EventTriggerao seu objeto de jogo. Isso nos dá acesso ao BaseEventDataobjeto retornado do evento, informando coisas como o objeto que criou o evento. Então você pode fazer 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);

Em seguida, podemos criar um método para manipular eventos, a assinatura deve corresponder à do nosso delegado. Portanto, ele precisa retornar voide aceitar BaseEventDatacomo seu primeiro e ú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.
}

Por fim, para adicionar dinamicamente o 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 você estiver usando a versão 5.3.3 ou superior, use esta linha em vez da última linha acima, delegados será depreciado :

eventTrigger.triggers.Add(entry); 
MichaelHouse
fonte
Parece que, quando você adiciona dinamicamente um manipulador, ele não aparece no inspetor. A gaveta ainda mostra "Lista vazia" para os delegados
vexe 6/12/14
Está correto. Os manipuladores adicionados a partir do código são separados dos manipuladores "persistentes" mostrados no inspetor; além disso, você é responsável por limpar esses manipuladores (diferentemente dos persistentes, dos quais o Unity cuida de você).
Joe Strout
11

A palavra é que a delegate{}sintaxe encontrada na minha resposta anterior é obsoleta, existe outra maneira de fazer isso usando a notação 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 você pode passar o botão para tornar as coisas um pouco mais 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
fonte
Lembre-se de que esta estratégia é apenas para o OnClickevento. Para adicionar outros eventos dinamicamente, você precisa seguir as instruções na minha outra resposta.
MichaelHouse
0

Crie um novo script, ao longo das linhas 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 implementa na interface IPointerClickHandler (entre muitas outras interfaces disponíveis ). Simplesmente anexar esse script a um elemento da interface do usuário permitirá que ele intercepte eventos de clique (ou qualquer outro evento para o qual você implemente a interface).

A próxima etapa é simplesmente adicionar dinamicamente esse script como um componente ao elemento da interface do usuário que você deseja:

myButton.AddComponent<EventHandler>();

Isso adicionará o script como um componente myButtone, na próxima vez que clicar no botão, obterá informações sobre qual botão foi clicado e onde o clique ocorreu.

Isso fornece mais informações sobre o evento em comparação com minhas outras respostas.

MichaelHouse
fonte
0

Como a unidade implementa a interface do usuário é como qualquer outro componente da unidade. Você adiciona GameObject e anexa componentes de interface do usuário a ele. Depois de ter o objeto do jogo, você pode obter os componentes da interface do usuário e alterar as propriedades.

A referência da API para interface do usuário pode ser encontrada no namespace UnityEngine.UI, a referência da API para BUtton é http://docs.unity3d.com/ScriptReference/UI.Button.html

Consulte a publicação http://blog.trsquarelab.com/2015/03/new-ui-implementation-using-c-scripts.html para obter mais informações sobre como acessar a interface do usuário a partir de scripts C #

Ranjith
fonte