- Home /
ArgumentException: Getting control 0's position in a group with only 0 controls when doing Repaint Aborting - why? C#
I saw this error on google many times and now I got it too and just can't figure out why it's doing it
and I know it's 1 of most asked Questions but in all answers I saw I can't pint point what's going on here?
because it seems that this error is very random. Does anyone know when it happenes?
and why if I leave only GUI.Box(new Rect(0,0,50,50),"dsfg"); no error
but every time I press a controll I get only 1 error for all layouts even if I remove area
some else script access this script and changes Guib to true or false with event. ...
If I get rid of all that GUILayouts I get no more errors why?
void OnGUI () {
GUI.depth = 2;
if (Guib){
GUI.skin = GuiSkin;
GuiF();
}
}
void GuiF(){
GUI.Box(new Rect(0,0,50,50),"dsfg");
GUILayout.BeginArea(new Rect(0,0,Screen.width,Screen.height));
GUILayout.Box("I'm Name");
GUILayout.Box("I'm Health");
GUILayout.Box("I'm Stamina");
GUILayout.Box("I'm Nutrition");
GUILayout.Box("I'm fOOd");
GUILayout.Box("I'm Water");
GUILayout.Box("I'm Bladder S**T");
GUILayout.Box("I'm Bladder water");
GUILayout.Box("I'll get back to this later");
GUILayout.Box("tho I think that's all I need");
GUILayout.EndArea();
}
I've read many of this type of errors but just can't figure out
//ArgumentException: Getting control 0's position in a group with only 0 controls when doing Repaint
//Aborting
//UnityEngine.GUILayoutGroup.GetNext () (at C:/BuildAgent/work/812c4f5049264fad/Runtime/ExportGenerated/Editor/GUILayoutUtility.cs:423)
//UnityEngine.GUILayoutUtility.BeginLayoutArea (UnityEngine.GUIStyle style, System.Type LayoutType) (at C:/BuildAgent/work/812c4f5049264fad/Runtime/ExportGenerated/Editor/GUILayoutUtility.cs:190)
//UnityEngine.GUILayout.BeginArea (Rect screenRect, UnityEngine.GUIContent content, UnityEngine.GUIStyle style) (at C:/BuildAgent/work/812c4f5049264fad/Runtime/ExportGenerated/Editor/GUILayout.cs:211)
//UnityEngine.GUILayout.BeginArea (Rect screenRect) (at C:/BuildAgent/work/812c4f5049264fad/Runtime/ExportGenerated/Editor/GUILayout.cs:201)
//PlayerS.GuiF () (at Assets/Scripts/_PlayerScripts/PlayerS.cs:52)
//PlayerS.OnGUI () (at Assets/Scripts/_PlayerScripts/PlayerS.cs:42)
thanks in advance
I'm experiencing this problem with EditorWindow.
void OnGUI()
{
if (Event.current.type != EventType.Repaint) return;
if (prefs == null)
{
EditorGUILayout.LabelField("Prefs is null"); // this throws the error
return;
}
......
}
I don't understand how i'm supposed to create editor for bunch of lists with different types if I can't change the values on the OnGUI where the actual input is given from the EditorGUILayout functions. I have used this code on a different project without any problems. I didn't even have the first if (if not repaint then return) before and it worked.
Answer by Bunny83 · Feb 26, 2013 at 12:37 PM
That's quite simple. The reason for this error is always the same. You changed the content of your GUI between the Layout and Repaint event. OnGUI is called for many different events (See the EventType enum for the full list).
Before each event Unity calls an additional Layout event. In this event Unity collects the information how many elements you have at the moment and hoe they are nested. This information is needed by the Layouting system.
When the actual event is processed it's vital that OnGUI has the same content as it has when the Layout event was called. That's why you shouldn't place any logic that changes the state of your GUI inside OnGUI. If you want place it in OnGUI, wrap it in
if (Event.current.type == EventType.Repaint)
{
//
}
When you change the state **at the end** of OnGUI, so the elements aren't affected since they are already drawn.
Or use
if (Event.current.type == EventType.Layout)
{
//
}
when you place your code before the actual GUI elements.
Anyway in general it's better to put any logic in Update.
edit
On this question i've posted a quite detailed post how the GUI system works if you want to gain some more knowledge about Unity ;).
I don't get it. How is it possible that when doing
state = EditorGUILayout.Toggle(state, "$$anonymous$$y Toggle")
the function retains the same value for state between Layout and Repaint??
I'm confused because the $$anonymous$$ouseDown event is triggered between them, so the return value is making state it's opposite and the re-injected state has then changed between the two events! I'm missing a key element here...
@Bunny83 gave some reference, but was confusing for dummy as I'm. So lets start from beginning. OnGUI is processed in several phases per refreshing frame. Important for the problem are "Layout" phase and "Repaint" phase. "Layout" phase happen before "Repaint", and if "Layout" phase counts 5 GUI elements to be layout, in "Repaint" phase should have also 5 GUI elements to paint. Problem is that code in OnGUI in phases can be evaluated differently, meaning that in same pass(frame), "Guib" can be "true" in "Layout" and "false" in "Repaint" or viceversa, so number of elements will be different. Just to Note also, I've case that was no error in Editor mode, but error was thrown in Playmode, and only once, on later passes both phases had same evaluation of the flags, bools, toogles...and so same number of GUI elements.
see image
public void OnGUI(Rect rect) {
if(EditorApplication.isPlaying){
_count++;
Debug.Log("OnGUI ("+_count+") EventType:"+Event.current.type);
}
//if(Event.current.type==EventType.Repaint)
//if(Event.current.type==EventType.Layout)
if (LogicEditorWindow.ActiveGameObject != null)
{
if(EditorApplication.isPlaying)
Debug.Log("("+_count+") EventType:"+Event.current.type);
// if(Event.current.type==EventType.Layout)
// if(Event.current.type==EventType.Repaint)
this.DoLogicList();
}
}
}
So SOLUTION is that in "Layout" phase you set flags/bools, and if that flags are set then you paint in "Repaint" phase.
private bool __showLayoutList;
public void OnGUI(Rect rect) {
//if(Event.current.type==EventType.Repaint)
if(Event.current.type==EventType.Layout) {
__showLayoutList = false;
if (LogicEditorWindow.ActiveGameObject != null)
{
__showLayoutList = true;
}
}
if (EditorApplication.isPlaying) {
__count++;
Debug.Log("OnGUI (" + __count + ") EventType:" + Event.current.type);
}
if (__showLayoutList) {
if (EditorApplication.isPlaying)
Debug.Log("(" + __count + ") EventType:" + Event.current.type);
this.DoLogicList();
}
}
Answer by BLooDBuRNiNG · May 04, 2014 at 10:18 AM
Hello everybody,
I found a simple way to fix this error, the following solving worked for me :
I believe that the problem come from the parameters id that you put in the function : GUI.Window static function Window(id: int, clientRect: Rect, func: WindowFunction, text: string): Rect;
It look that you use the same id, for different windows. example instead to have : FPS Script :
startRect = GUI.Window(**0** startRect, DoMyWindow, "");
Stat Script :
window_stat = GUI.Window(**0**, window_stat, Do_My_Window_Stat, "");
FPS Script :
startRect = GUI.Window(**0**, startRect, DoMyWindow, "");
You can solve this error which changing the window id :
Stat Script :
window_stat = GUI.Window(**1**, window_stat, Do_My_Window_Stat, "");
What you should do to help you is to use an enumeration, to be sure that you never use several time the same id:
enum e_which_window
{
E_WINDOW_FPS_COUNTER,
E_WINDOW_STAT_COUNTER
}
FPS Script : startRect = GUI.Window(e_which_window.E_WINDOW_FPS_COUNTER, startRect, DoMyWindow, "");
Stat Script :
window_stat = GUI.Window(e_which_window.E_WINDOW_STAT_COUNTER, window_stat,
Do_My_Window_Stat, "");
I hope that my answer helped you ;)
I get the same error, except that I have programmed nothing with OnGUI. I get it everytime the Inspector window refreshes when I press on a different GameObject.
Answer by Quatum1000 · Mar 02, 2016 at 06:46 AM
Getting control 0's position in a group with only 0 controls when doing scrollWheel
If you got any Error like this try to use simply return; after your action that cause the Error.
Event e = Event.current;
if (e.type == EventType.scrollWheel) {
var dir = e.delta;
if (dir.y < 0)
TrackSelOffs--;
else
TrackSelOffs++;
TrackSelOffs = Mathf.Min(Mathf.Max(0, TrackSelOffs), TracksMax + 1);
return;
}