ArgumentException: Getting control 0's position in a group with only 0 controls when

There are some codes. When i press the return key the console debug : ArgumentException: Getting control 0’s position in a group with only 0 controls when doing KeyDown Aborting .Why?

1.private var input:String="";
2.private var showChat:boolean=false;
3. 
4.function OnGUI()
5.{
6.    
7.    if(Event.current.type==EventType.KeyDown  Event.current.character=="\n"  input.Length<=0)
8.    {
9.        showChat=!showChat;
10.    }
11.    if(showChat)
12.    {
13.        ShowChat();
14.    }   
15.}
16. 
17.function ShowChat()
18.{
19.    GUILayout.Label("DSFSDFDSF");
20.}

Try putting your keydown check inside the Update function, also use Input.GetKeyDown instead of checking Event.current, since Event.current is always null inside the Update function.

The reason you get that error message is, OnGUI is called several times per frame, and if you draw different number of controls in one of those called in the same frame, you might get this error message.

Hmmm…Thank you very much.

If i change like this

function ShowChat()
{
GUI.Label(Rect(0,0,100,100),“ADD”);
}

It would no errors.Why?

Well, that’s a bit complicated, here’s what I know:

OnGUI is called by unity several times per frame with different events active. Normally, when there are no inputs active, it gets called twice with events Layout and Repaint. During the Layout call, your GUILayout calls are processed and positions and sizes of the controls are calculated, nothing is actually drawn on the screen. Secondly, it’s called with Repaint event active, this time the controls are actually drawn with the calculated positions and sizes. It’s also called an extra time when there’s an active input (mouse, keyboard etc.) and this call is always made last and it also causes drawing on the screen.

Now, in your case with the GUILayout call, and you press the enter key, here’s what happens:

  • OnGUI is called with Event.current = EventType.Layout
    Since your showchat variable is false, no GUILayout calls are made and no position and size for any control is cached

  • OnGUI is called with Event.current = EventType.KeyDown
    Your showchat variable is set to true and GUILayout.Label is called and unity tries to draw the label on the screen. But since it’s a GUILayout call, it needs the position and size of the control that should have been calculated in the Layout event, but we didn’t make any GUILayout calls in the Layout event and nothing was calculated, so unity throws the error “Getting control 0’s position in a group with only 0 controls when doing keydown”.

In the case when you call GUI.Label, it’s like an immediate draw call, the Layout event does not calculate anything for GUI calls (not GUILayout), so the GUI.Label can be drawn during the KeyDown event and unity doesn’t give any error.

I might be wrong about the order of events, but this is the basic reason for the error.

8 Likes

I think i catch what you mean.Thank you very much.It’s very kind of you.

Thanks for the clear explanations, worked very well indeed!

Bye,

Jean

could you please give me an example? my code doesn’t work

private void OnGUI(){

DropAreaGUI ();

}

private void DropAreaGUI(){

var e = Event.current.type;

if (e == EventType.DragUpdated) {

DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

} else if (e == EventType.DragPerform) {

DragAndDrop.AcceptDrag ();

foreach (GameObject draggable in DragAndDrop.objectReferences) {

EditorGUILayout.BeginVertical ();

draggable.name = EditorGUILayout.TextField ("Current object name", draggable.name);
draggable.transform.position = EditorGUILayout.Vector3Field ("Position", draggable.transform.position);

EditorGUILayout.EndVertical ();
}
}
}

You should not use EditorGUILayout inside EventType check. You can store the objectReferences to a list first, then call EditorGUILayout outside of EventType check.