[SOLVED] GUI.RepeatButton returns true-false-true-false..

I have following code in my OnGUI

state = GUI.RepeatButton(rect, controlContent);

and it returns not true-true-true-true, as I expected, but true-false-true-false (the problem was that I was not able to detect an exact moment a button was pressed, because when current state was TRUE then a previous state always was FALSE, but I was expected a current=true and old=true at this moment).

Ok, I found that this is an as-designed behavior, and even some explanations about why so… and now I compare current with before last state (instead of last one) to detect if user just pressed or already holds buttons for some time…

…and It seems all right, but I worry about stability of this solution… Is there any assurance that it always will return TRUE-FALSE-TRUE-FALSE when held? Is this behavior documented somewhere? Couldn’t it become the “TRUE-TRUE” or “TRUE-FALSE-FALSE-TRUE-FALSE-FALSE” or something else in future Unity version?

P.S. Of cause I now about the solution where I could just change state in OnGUI and react it in Update ( http://forum.unity3d.com/threads/repeatbutton-true-false.19527/ ), but I’m trying to avoid an Update in script attached to about 500 gameobjects (my own gui system is based on gameobject hierarchy) because of overhead (I haven`t made the performance tests but I already believe the opinion that “any Reflection is overhead, especially for mobile platform”, and Update, FixedUpdate and others are called via reflection afaik).

EDIT2: I removed previous “EDIT” because I wrote them with misunderstanding about a key of the answers… sorry :slight_smile:

Check the value of state in Update, or during the repaint event.

function OnGUI () {
	state = GUI.RepeatButton(rect, controlContent);
	if (Event.current.type == EventType.Repaint) {
		Debug.Log ("OnGUI: " + state);
	}
}

function Update () {
	Debug.Log ("Update: " + state);
}

To answer your question, no, your solution is not stable.

RepeatButton only returns true on the “Repaint” and “MouseUp” events. If the user drags the mouse while holding the button, the true-false-true-false pattern breaks.

Run this code to see what I mean:

public void OnGUI()
{
    EventType eventType = Event.current.type;
    bool isPressed = GUILayout.RepeatButton("Button");
    Debug.Log(eventType + ": " + isPressed);
}

The output will look like:

Layout: False
MouseDown: False
Layout: False
Repaint: True
Layout: False
MouseDrag: False
Layout: False
Repaint: True
Layout: False
MouseUp: True

Like @Eric5h5 said, you need to update state on the repaint event. The correct solution is:

public bool state;

public void OnGUI() 
{
    bool isPressed = GUILayout.RepeatButton("Button");

    if (Event.current.type == EventType.Repaint)
	    state = isPressed;

    if (state)
	    OnClickActions();
    else
	    OnHoldActions();
}

bool oldState;

 state = GUI.RepeatButton(rect, controlContent);
 if(state != oldState)
 {
 //  do the thing
 oldState = state;
 }

you can try this, haven’t got the time to test but the theory is there :smiley: