1

I have a UI button. I want to show a text when the user is pressing the button and hide the text when the user releases the button.

How can I do this?

Hellium
  • 7,206
  • 2
  • 19
  • 49
Marc
  • 11
  • 1
  • 1
  • 2
  • 4
    Either use the script given in the answer given here [How to detect click/touch events on UI and GameObjects](https://stackoverflow.com/questions/41391708/how-to-detect-click-touch-events-on-ui-and-gameobjects), or use an [`EventTrigger`](https://unity3d.com/learn/tutorials/topics/user-interface-ui/ui-events-and-event-triggers) and call the functions you want in the `OnPointerDown` and `OnPointerUp` events. – Hellium Apr 01 '19 at 05:29
  • In order to call a function while the button is pressed, use a boolean you set to `true`/`false` in the previous events, and check the value of the boolean in the `Update` function before calling the function you want. – Hellium Apr 01 '19 at 05:38

2 Answers2

6

this anwser is basically fine but there is a huge drawback: You can't have additional fields in the Inspector since Button already has a built-in EditorScript which overwrites the default Inspector - You would need to extend this via a custom Inspector every time.


I would instead implement it as completely additional component implementing IPointerDownHandler and IPointerUpHandler (and maybe also IPointerExitHandler to reset also when exiting the button while holding the mouse/pointer still pressed).

For the doing something while the button stays pressed I'ld use a Coroutine.

In general I'ld use UnityEvents:

[RequireComponent(typeof(Button))]
public class PointerDownUpHandler : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerEnterHandler, IPointerExitHandler
{
    public UnityEvent onPointerDown;
    public UnityEvent onPointerUp;

    // gets invoked every frame while pointer is down
    public UnityEvent whilePointerPressed;

    private Button _button;

    private void Awake()
    {
        _button = GetComponent<Button>();
    }

    private IEnumerator WhilePressed()
    {
        // this looks strange but is okey in a Coroutine
        // as long as you yield somewhere
        while(true)
        {
             whilePointerPressed?.Invoke();
             yield return null;
        }
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        // ignore if button not interactable
        if(!_button.interactable) return;

        // just to be sure kill all current routines
        // (although there should be none)
        StopAllCoroutines();
        StartCoroutine(WhilePressed);

        onPointerDown?.Invoke();
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        StopAllCoroutines();
        onPointerUp?.Invoke();
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        StopAllCoroutines();
        onPointerUp?.Invoke();
    }

    // Afaik needed so Pointer exit works .. doing nothing further
    public void OnPointerEnter(PointerEventData eventData) { }
}

Than you can reference any callback in onPointerDown, onPointerUp and whilePointerPressed just the way you would do it with the onClick event of the Button.

derHugo
  • 83,094
  • 9
  • 75
  • 115
2

You have to create your own custom button by extending Button class and override method OnPoiterDown and OnPointerUp. Attach MyButton component instead of Button to your gameobject

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

public class MyButton : Button
{

    public override void OnPointerDown(PointerEventData eventData)
    {
        base.OnPointerDown(eventData);
        Debug.Log("Down");
        //show text
    }

    public override void OnPointerUp(PointerEventData eventData)
    {
        base.OnPointerUp(eventData);
        Debug.Log("Up");
        //hide text
    }
}
derHugo
  • 83,094
  • 9
  • 75
  • 115
Pratik
  • 413
  • 3
  • 6