Search Unity

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

Discussion in 'Immediate Mode GUI (IMGUI)' started by langshan, May 7, 2012.

  1. langshan

    langshan

    Joined:
    Mar 14, 2012
    Posts:
    79
    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?

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

    dodo

    Joined:
    Jul 13, 2011
    Posts:
    49
    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.
     
  3. langshan

    langshan

    Joined:
    Mar 14, 2012
    Posts:
    79
    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?
     
  4. dodo

    dodo

    Joined:
    Jul 13, 2011
    Posts:
    49
    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.
     
    nixalott, RYL123, StellarVeil and 5 others like this.
  5. langshan

    langshan

    Joined:
    Mar 14, 2012
    Posts:
    79
    I think i catch what you mean.Thank you very much.It's very kind of you.
     
  6. Jean-Fabre

    Jean-Fabre

    Joined:
    Sep 6, 2007
    Posts:
    429
    Thanks for the clear explanations, worked very well indeed!

    Bye,

    Jean
     
  7. buhanka1994

    buhanka1994

    Joined:
    Mar 2, 2018
    Posts:
    1
    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 ();
    }
    }
    }

     
  8. lokinwai

    lokinwai

    Joined:
    Feb 11, 2015
    Posts:
    174
    You should not use EditorGUILayout inside EventType check. You can store the objectReferences to a list first, then call EditorGUILayout outside of EventType check.