I’ve been spending a fair bit of time with Unity’s UGUI for my latest project. Having wrestled with it for a while, in some ways I wish I’d stuck with NGUI, but I’ve learned a lot along the way so it’s not all bad.
In my UI I have some buttons which open sub menus, but I wanted to be able to rename the menu item as well. Since the target is mobile, right click is out. I thought a long press would be an intuitive way for users to change the name, so I had a quick look to see if anyone had already done this.
I came across this Unity forum post which has a script/component that works quite nicely.
The thing is, I’ve been avoiding including any
Update() methods in my UI to keep it as speedy as possible, so I rewrote that long press script to avoid
Update() and it’s turned out to be a fair bit quicker as well:
public class ButtonLongPress : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler
[Tooltip("How long must pointer be down on this object to trigger a long press")]
private float holdTime = 1f;
// Remove all comment tags (except this one) to handle the onClick event!
//private bool held = false;
//public UnityEvent onClick = new UnityEvent();
public UnityEvent onLongPress = new UnityEvent();
public void OnPointerDown(PointerEventData eventData)
//held = false;
public void OnPointerUp(PointerEventData eventData)
public void OnPointerExit(PointerEventData eventData)
private void OnLongPress()
//held = true;
So what is this doing?
Invoke calls a method after a certain number of seconds – in this case set by
holdTime. The Invoke is cancelled if the mouse button is released or if the mouse leaves the button before the time is up. Not including an update method means there’s no calculations every frame (and don’t forget to remove all your empty update methods which still get added to the list).
It’s been my experience that adding this component to an existing button overrides the button’s
onClick event if the long press is invoked. But I’ve noticed for some people the
onClick event still occurs, so I included the ability for this component to handle all clicks – just remove the comment tags.
One downside I’ve noticed is that if you add this to a lot of UI elements and then decide you want to change the default hold time in the script, Unity will have already serialized it on all those elements so changing it will have no effect.
If that happens to you, you can either change it so it gets the value from a singleton or another solo class (in my case my MenuManager) or you can change the name of the
holdTime field and the value. Then it will reset all those instances to your new value.