- Home /
Event System: Check which button has been clicked?
So, I'm having the hardest time figuring out how to do something that really should just be in the API.
I'm using the "new" GUI system and I instantiate buttons at run time. When I click a button, I want to find out which instantiated button I have clicked. I can't pass it through in the OnClick() method in the inspector because it hasn't been created yet, I can't set the parameter of the method in the OnClick() method through code (which I really think you should just be able to write something like button.OnClick().PersistentMethod(0).argument = button.gameObject) and I can't seem to get the AddListener() thing working either (and yes, I have used the proper syntax but it's just not working).
So is there any way I can click the button and find out the gameobject that has been clicked? Sounded simple enough in my head.
The buttons are in an array of Buttons (Button[]) so is that part of the issue? I'm trying to, when instantiate them, set the parameter of the method used in OnClick() to be that particular button (button[x].gameObject).
Add a Listener by code and make it call a function that accepts the Buton that was pressed as a parameter.
button.onClick.AddListener(delegate { ButtonClick(button); });
public void ButtonLeftClick(Button button) {
Debug.Log(button.name + " was clicked.");
}
Answer's been given; and this AddListener Delegate stuff didn't work for the instantiated buttons.
Answer by JoshuaMcKenzie · Nov 08, 2015 at 03:12 PM
if you're using the Eventsystem then you also have access to the Event Handlers as well which are super useful. An example script you can have attached to your button prefab that you instaniate:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
/// <summary>
/// Unity Behavior's eventsystem needs a:
/// 1a) collider and phyics raycaster component on the camera(for 3d gameobject) or
/// 1b) a graphics raycaster component on the Canvas (for UI)
/// 2) a monobehavior script (like the one below)
/// 3) and an eventsystem gameobject (added by default when you create a UI->Canvas,
/// only one can exist in the scene) to work
///
/// This script simply catches click events related to the object and passes it to where
/// you need it to go
/// </summary>
public class OnClickRelay : MonoBehaviour, IPointerClickHandler
{
public void OnPointerClick(PointerEventData eventData)
{
//passes data to your button controller (or whater you need to know about the
//button that was pressed), informing that this game object was pressed.
ButtonController.instance.ButtonPressed(gameobject, eventData);
}
}
PointerEventData has tons of useful info about the click event. for example how long you've clicked and if its a double click. you won't always need it, but the interface requires it as a parameter and it never hurts to pass it along to the controller that wants info on the button pressed.
Okay, brilliant! You've done it.
I was hoping I wouldn't have to use another script but... it gets the job done!
For anyone wondering how exactly to use this script to check which GUI Button you've just pressed, you use the eventData variable that is passed through and get its 'selectedObject' value:
public void ButtonPressed(PointerEventData ev){
Debug.Log (ev.selectedObject); //This prints out the button gameobject that was pressed!
}
I was thinking that just accessing the 'currentSelectedGameObject' from the eventsystem was the same thing but... it turns out it isn't. Problem solved! Thank you SO much, Joshua.
Answer by starikcetin · Nov 07, 2015 at 07:31 PM
Think reversed. Instead of checking which button is pressed, simply send a parameter to let script know which button called callback. Like:
public void ButtonPressCallback (int pressedIndex)
{
if(pressedIndex == 1)
{
Debug.Log("Button 1 pressed");
}
}
But how do I assign the value of the parameter (pressedIndex)? I can't do it through code (as I have explained because there's nothing in the API that allows you to access this value) and I can't do it in the inspector because the buttons haven't been instantiated yet. $$anonymous$$y idea was to pass through the button gameObject rather than a value, but either way I need to know how to assign this parameter to be either.
Why are you using OnGUI? Use eventSystem ins$$anonymous$$d. It allows you to pass pirimitive types (int, string etc.) as parameter.
Your answer
Follow this Question
Related Questions
Android Buttons Responding Poorly To Touch Controls 2 Answers
How can use OnPointerClick in a generic way? 1 Answer
GUI Button to toggle true false when pressed 1 Answer
button pressed twice / Conversation text skip 5 Answers
GUI problem 1 Answer