Search Unity

Button Repeat

Discussion in 'UGUI & TextMesh Pro' started by LightStriker, Aug 23, 2014.

  1. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    I guess I'm blind - I am some times.

    In GUI, there's something called GUI.ButtonRepeat which fires every frame as long as the button is pressed. I was expecting - hoping - that the new GUI button would have event similar to Button Repeat, or that there would a similar class.

    However, I simply can't find it.

    On top, extending the existing GUI class appear to be a small puzzle on itself as the existing class have quite the extensive custom editor - and I deeply hate writing custom editor.

    So, how should go using the new GUI to make a button that fires every frame it is held down?
     
  2. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683
    add PointerDown & PointerUp events to set a bool?

     
    TechSupportIncoming1 likes this.
  3. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Add? What? Where? The only event in the button Inspector is "On Click".
     
  4. Legi

    Legi

    Joined:
    Jul 25, 2013
    Posts:
    20
    Add an Event Trigger Component to the Button object and click on "Add New". There you have every event you can use on that button, including PointerDown and PointerUp.
     
    AlexMarinache likes this.
  5. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Thanks!

    EDIT: Huh... OnPointerDown is fired only once, the moment the mouse button is pressed. Ok, so how do I make this event repeat itself as long as it's held down?
     
    Last edited: Aug 23, 2014
  6. Legi

    Legi

    Joined:
    Jul 25, 2013
    Posts:
    20
    Set it up so a bool is set to true on the OnPointerDown event and set to false on the OnPointerUp event.
    In your Update method check that boolean. If its true, the button is held down.
     
    Shallow-Gibbs likes this.
  7. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    It's a rather backward way to do it, but I guess it will have to do...
     
  8. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    I have noted that this might be desirable to add in the future.
     
  9. thylaxene

    thylaxene

    Joined:
    Oct 10, 2005
    Posts:
    716
    You think?
    Personally it strikes me that reproducing all the old GUI system's elements at release might have been a good idea.
     
    Last edited: Nov 27, 2014
    TechSupportIncoming1 likes this.
  10. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Personally, I think the system is lacking some very important thing... Like... I dunno... C# Events?
     
  11. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    Is there a simpler way to handle onButtonDown events each frame now?
     
  12. sotec

    sotec

    Joined:
    Sep 14, 2012
    Posts:
    34
    nope still the **** pointerDown / pointerUp and bool technic, sad thing ><
     
  13. dchipman

    dchipman

    Joined:
    Jan 4, 2015
    Posts:
    39
    For anyone else that stumbles onto this like I did, I made the following script to streamline the repeat button functionality per the previously suggested solution until Unity comes up with something better. Did the trick for me. Probably add a cooldown or something (as needed) unless you really want it firing every frame.
    Just throw this MonoBehaviour on the same object as your button, assign the button property, and you're in business.

    using UnityEngine;
    using UnityEngine.UI;
    using UnityEngine.EventSystems;

    [RequireComponent(typeof(Button))]
    public class ButtonRepeater : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
    {
    public bool shouldRepeat { get { return _pointerData != null; } }
    public Button button = null;
    private PointerEventData _pointerData = null;

    private void Update()
    {
    if(shouldRepeat)
    {
    button.OnSubmit(_pointerData);​
    }​
    }

    public void OnPointerDown(PointerEventData eventData)
    {
    _pointerData = eventData;​
    }

    public void OnPointerUp(PointerEventData eventData)
    {
    _pointerData = null;​
    }​
    }
     
  14. tgouala-wellfiredLtd

    tgouala-wellfiredLtd

    Joined:
    Jun 8, 2013
    Posts:
    99
    Hi Dchipman.

    I could not make work your solution. I have a weird "Unexpected symbol '<internal>' " in the console that prevent me from compiling the code. Also I was a bit confused with the bool shouldRepeat. Why to not call it : "pointerIsDown".
     
  15. FromSkyToEnd

    FromSkyToEnd

    Joined:
    May 2, 2013
    Posts:
    3
    since earlier code had hidden symbols that broke compile here is one that works...
    button should be assigned automatically, while I introduced a delay for the repeat to start and interval for it to work.
    might have a bug, but seems to work

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.UI;
    4. using UnityEngine.EventSystems;
    5.  
    6. [RequireComponent(typeof(Button))]
    7. public class ButtonRepeat : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
    8. {
    9.     [SerializeField]
    10.     private float m_repeatDelay = 1f;
    11.     [SerializeField]
    12.     private float m_repeatRetriggerInterval = 0.1f;
    13.     private Button m_button;
    14.     private PointerEventData m_pointerData = null;
    15.     private float m_lastTrigger = 0;
    16.  
    17.     private void Awake()
    18.     {
    19.         m_button = transform.GetComponent<Button>();
    20.     }
    21.  
    22.     private void Update()
    23.     {
    24.         if (m_pointerData != null)
    25.         {
    26.             if(Time.realtimeSinceStartup - m_lastTrigger >= m_repeatDelay)
    27.             {
    28.                 m_lastTrigger = Time.realtimeSinceStartup - (m_repeatDelay - m_repeatRetriggerInterval);
    29.                 m_button.OnSubmit(m_pointerData);
    30.             }
    31.         }
    32.     }
    33.  
    34.     public void OnPointerDown(PointerEventData eventData)
    35.     {
    36.         m_lastTrigger = Time.realtimeSinceStartup;
    37.         m_pointerData = eventData;
    38.     }
    39.  
    40.     public void OnPointerUp(PointerEventData eventData)
    41.     {
    42.         m_pointerData = null;
    43.         m_lastTrigger = 0f;
    44.     }
    45. }
     
    dappledore likes this.
  16. IzzySoft

    IzzySoft

    Joined:
    Feb 11, 2013
    Posts:
    376
    i think people want a mouse held event like this..
    ex:
     
  17. FatIgor

    FatIgor

    Joined:
    Sep 13, 2015
    Posts:
    29
    Thank you. Always grateful for code that saves me having to do something. Especially when free. Worked fine.
     
  18. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,403
    still works, one gotcha to watch out inside editor:
    For the first click, it fires OnPointerUp() right after OnPointerDown(), even if you are holding mouse down!

    So click game view first to activate it(?), then click and hold the button to see real results..