- Home /
Unity 4.6 add OnPointerDown Listener to Button
I can add an onClick listener to one of my buttons using:
JumpButton.onClick.AddListener(() => {Jump(); });
I want do the same with another button only I want the event to be a an OnPointer or OnMouse down event. I tried the following:
RotateButton.OnPointerDown.AddListener(() => {RotateVehicle(); });
But this yields error:
Expression denotes a 'method group', where a 'variable', 'value or 'type was expected
Thank you in advance.
Assu$$anonymous$$g that RotateButton
has type UI.Selectable
, OnPointerDown is a function. I haven't messed around with the new GUI, yet, but that would apparently explain the error.
Answer by orb · Sep 12, 2014 at 11:28 PM
There's no AddListener() method on OnPointerDown(), so you'll have to implement it the old-fashioned way, by implementing the right interfaces:
using UnityEngine;
using UnityEngine.EventSystems;
public class BT : MonoBehaviour, IPointerDownHandler
{
public void OnPointerDown(PointerEventData data)
{
}
}
etc.
It seems really odd that there is not a listener for pointer down.
And I apologize, I should clarify.
The function that rotates the vehicle is on a script attached to an instantiated prefab, therefore, I was trying to use the workflow to one of my other questions as shown here: http://answers.unity3d.com/questions/788493/unity-46-access-button-by-script.html
How would I implement your solution within that workflow?
I'd use a helper script that implements the interfaces, and calls a delegate, so you add the listener to the helper component ins$$anonymous$$d of directly on the buttons. I'd also go look for a request for this functionality in Feedback and vote it up :)
Orb, thank you for your response.
As you've might have guessed, I'm not a seasoned programmer ;).
Can you provide a basic test case of your solution? I don't expect you to completely write the code for me but I could use a little more guidance.
If you wonder why there is no "listener" for input it's because Unity uses Reflection to find all classes that have an Interface of the type. If you don't know what reflection is there is about million things about it on $$anonymous$$SDN. It pretty much comes down to code that can look at class and get a list of details about that class. It then has the power to call the functions it wants. (What I just said is super incredibly dumbed down version of what it truly does)
I'm looking into this https://github.com/AyARL/UnityGUIExamples
I can't believe there isn't a simpler way to go about this. Anyway, I used TriggerSetup.cs from the above link and attached it to my Rotate button.
I can't show the entire script. I know its not very convenient but you'll probably need to view the entire TriggerSetup.cs script from the above link.
As you'll see below, In TriggerSetup.cs, I referenced the instantiated prefab's NVehicleController script. I placed my controller.RotateVehicle() call within the OnPointerDown() function.
Now the Rotate button does indeed trigger the RotateVehicle() function within NVehicleController using onPointerDown, however, while it shows the debug message within that function, my vehicle isn't rotating so I'm thinking that the RotateFunction() is getting canceled right away because of the error:
Type IPointerEnterHandler expected EventTrigger received. i:1. Object reference not set to an instance of an object
Partial TriggerSetup.cs:
void Start()
{
// ===== $$anonymous$$y Addition ====
GameObject vehicle = GameObject.FindGameObjectWithTag("Vehicle"); // This is an instantiated prefab
controller = vehicle.GetComponent<NVehicleController>();
// ===== END $$anonymous$$y Addition ====
eventTrigger = gameObject.GetComponent<EventTrigger>();
AddEventTrigger(OnPointerClick, EventTriggerType.PointerClick);
AddEventTrigger(OnPointerEnter, EventTriggerType.PointerEnter, toggle);
AddEventTrigger(OnPointerExit, EventTriggerType.PointerExit);
AddEventTrigger(OnPointerDown, EventTriggerType.PointerDown);
AddEventTrigger(OnPointerUp, EventTriggerType.PointerUp);
}
// Use listener with no parameters
private void AddEventTrigger(UnityAction action, EventTriggerType triggerType)
{
// Create a nee TriggerEvent and add a listener
EventTrigger.TriggerEvent trigger = new EventTrigger.TriggerEvent();
trigger.AddListener((eventData) => action()); // ignore event data
// Create and initialise EventTrigger.Entry using the created TriggerEvent
EventTrigger.Entry entry = new EventTrigger.Entry() { callback = trigger, eventID = triggerType };
// Add the EventTrigger.Entry to delegates list on the EventTrigger
eventTrigger.delegates.Add(entry);
}
private void OnPointerDown()
{
textField.text = "OnPointerDown";
// $$anonymous$$y Addition
controller.RotateVehicle();
}