Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Unity 4.6 How Detect Button Event.

Discussion in 'UGUI & TextMesh Pro' started by Jason-Nash, Oct 3, 2014.

  1. Jason-Nash

    Jason-Nash

    Joined:
    Apr 30, 2014
    Posts:
    20
    Hi, Guys!
    I have 5 button on Canvas. In my code, I have created an array of buttons. all good!

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using UnityEngine.UI;
    5. using UnityEngine.EventSystems;
    6.  
    7. public class ButtonPressSystem : MonoBehaviour , IPointerDownHandler, IPointerUpHandler
    8. {
    9.     Button[] btn;
    10.    
    11.     void Awake()
    12.     {
    13.        GameObject gh = GameObject.Find("Canvas");
    14.        btn =  gh.GetComponentsInChildren<Button>();
    15.  
    16.        foreach (Button b in btn)
    17.        {
    18.  
    19.            print(b.name);
    20.        
    21.        }
    22.  
    23.     }
    24.    
    25.  
    26.     void Start ()
    27.     {
    28.  
    29.     }
    30.    
    31.     void Update ()
    32.     {
    33.        
    34.     }
    35.  
    36.  
    37.     public void OnPointerDown(PointerEventData eventData)
    38.     {
    39.        
    40.     }
    41.  
    42.     public void OnPointerUp(PointerEventData eventData)
    43.     {
    44.        
    45.     }
    46.  
    47.  
    48. }
    49.  
    50.    
    My script is not installed on the button!!!
    that is, I have a lot of buttons and how do I know which one is pressed?
    How i can detect OnPointerDown event?
     
  2. Mikeysee

    Mikeysee

    Joined:
    Oct 14, 2013
    Posts:
    155
    Why not simply:

    Code (CSharp):
    1. public class ButtonPressSystem : MonoBehaviour
    2. {
    3.     Button[] btn;
    4.  
    5.     void Awake()
    6.     {
    7.        GameObject gh = GameObject.Find("Canvas");
    8.        btn =  gh.GetComponentsInChildren<Button>();
    9.        foreach (Button b in btn)
    10.        {
    11.             b.onClick.AddListener(() => Debug.Log("Clicked!");      
    12.        }
    13.     }
    14. }
    15.  
     
    Jason-Nash likes this.
  3. Jason-Nash

    Jason-Nash

    Joined:
    Apr 30, 2014
    Posts:
    20
    Thank you for the reply, but that doesn't answer my question!
    I still don't know how to detect OnPointerDown event!
     
  4. AriathTheSage

    AriathTheSage

    Joined:
    Aug 25, 2014
    Posts:
    13
  5. Jason-Nash

    Jason-Nash

    Joined:
    Apr 30, 2014
    Posts:
    20
    Its doesn't work, in my script!

    Assets/ButtonPressSystem.cs(13,62): error CS0426: The nested type `InputButton' does not exist in the type `UnityEngine.EventSystems.PointerEventData'
     
  6. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    Use the EventTrigger component...
     
    Jason-Nash likes this.
  7. Jason-Nash

    Jason-Nash

    Joined:
    Apr 30, 2014
    Posts:
    20
    is it possible to detect button events from a different script that is not pinned on the button !
     
  8. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    You want the PointerDown and PointerUp events correct? In that case just use an EventTrigger...
     
    Jason-Nash likes this.
  9. Jason-Nash

    Jason-Nash

    Joined:
    Apr 30, 2014
    Posts:
    20
    Yes, but not from the button's scripts! I mean my script doesn't have to be pinned to the button.

    In my script i found all buttons on my "Canvas" like this:
    Code (CSharp):
    1. public class ButtonPressSystem : MonoBehaviour
    2. {
    3.     Button[] btn;
    4.     void Awake()
    5.     {
    6.        GameObject gh = GameObject.Find("Canvas");
    7.        btn =  gh.GetComponentsInChildren<Button>();
    8.        foreach (Button b in btn)
    9.        {
    10.              
    11.        }
    12.     }
    13. }
    And i need to detect all my button events from the script!
     
  10. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    You can still use an EventTrigger, you just need to add the EventTrigger component either from the editor or from your script, then add listeners...

    I've made a little extension methods to help you better understand what i mean

    File: EventTriggerExtension.cs
    Code (csharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using UnityEngine.Events;
    4.  
    5. namespace UnityEngine.EventSystems
    6. {
    7.     public static class EventTriggerExtension {
    8.      
    9.         public static EventTrigger GetEventTrigger(this GameObject gameObject)
    10.         {
    11.             EventTrigger trigger = gameObject.GetComponent<EventTrigger>();
    12.             if (trigger == null) trigger = gameObject.AddComponent<EventTrigger>();
    13.             return trigger;
    14.         }
    15.      
    16.         public static void AddEventListener(this EventTrigger trigger, EventTriggerType eventType, UnityAction<BaseEventData> callback)
    17.         {
    18.             if (trigger == null)
    19.                 return;
    20.          
    21.             if (trigger.delegates == null)
    22.                 trigger.delegates = new List<EventTrigger.Entry>();
    23.          
    24.             EventTrigger.Entry entry = trigger.delegates.Find(e => e.eventID == eventType);
    25.          
    26.             if (entry == null)
    27.             {
    28.                 entry = new EventTrigger.Entry();
    29.                 entry.eventID = eventType;
    30.                 entry.callback = new EventTrigger.TriggerEvent();
    31.                 trigger.delegates.Add(entry);
    32.             }
    33.          
    34.             entry.callback.AddListener(callback);
    35.         }
    36.     }
    37. }

    And here is a little demonstration of the usage:
    File: Test.cs
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.Events;
    4. using UnityEngine.EventSystems;
    5.  
    6. public class Test : MonoBehaviour {
    7.  
    8.     void Start ()
    9.     {
    10.         EventTrigger trigger = this.gameObject.GetEventTrigger();
    11.         trigger.AddEventListener(EventTriggerType.PointerDown, TestA);
    12.         trigger.AddEventListener(EventTriggerType.PointerUp, TestB);
    13.     }
    14.  
    15.     public void TestA(BaseEventData eventData)
    16.     {
    17.         Debug.Log("Down " + Random.Range(0, 100000));
    18.     }
    19.  
    20.     public void TestB(BaseEventData eventData)
    21.     {
    22.         Debug.Log("Up " + Random.Range(0, 100000));
    23.     }
    24. }
     
    justinbowes and Jason-Nash like this.
  11. Jason-Nash

    Jason-Nash

    Joined:
    Apr 30, 2014
    Posts:
    20
    Thank you very much, that's exactly what i was looking for!
     
  12. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    No problem, i am glad i could help.
     
    Jason-Nash likes this.
  13. Capn_Andy

    Capn_Andy

    Joined:
    Nov 20, 2013
    Posts:
    80
  14. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
  15. Capn_Andy

    Capn_Andy

    Joined:
    Nov 20, 2013
    Posts:
    80
    Sure, I have several menus in the game I'm working on and each has several "Button" types. To control this menu, users use a mix of Keyboard, Mouse, and Controllers. I would like to make the game play a sound effect any time a button is actuated, and also to make a sound effect any time a button is highlighted (or "selected" in Unity's terms).

    Right now this is possible with Mouse controls; PointerEnter can be extended to play an audio file, and PointerClick can be extended as well, which is just what we want.

    However, controllers and keyboard input do not trigger any of the events that are labelled "Pointer."

    The "OnSubmit" function looks like it might be what I need for the actuation sound effect, but the function is sealed and I can't extend it.

    Likewise, there is no obvious keyboard equivalent of "PointerEnter" for a Button; there is "OnSelected", but this triggers any time the button gains focus (such as when a menu is created and one of the elements is pre-populated). Other methods (like "OnMove") seem to trigger too frequently (such as on "movement" events that result in no actual movement, like pressing left or right on a vertical-only menu).

    In short,

    Is there a way to make the New UI system play sound effects on movement + actuation, when not using a mouse?
     
  16. ChoMPi

    ChoMPi

    Joined:
    Jul 11, 2013
    Posts:
    112
    Well it seems the EventTrigger component does not support OnSubmit and as you said the Button's OnSubmit method is not overridable, so your last resort is to create a simple script that implements the ISubmitHandler interface...

    Code (csharp):
    1. using System;
    2. namespace UnityEngine.EventSystems
    3. {
    4.     public interface ISubmitHandler : IEventSystemHandler
    5.     {
    6.         void OnSubmit(BaseEventData eventData);
    7.     }
    8. }
    Shouldn't be too hard to do that, but if you need help just write another post...

    And as for the OnSelect and OnDeselect you could create a simple manager to track when the events are triggered...