- Home /
Why control Id retreated from GUIUtility different from GUIUtility.keyboardControl
Nice day guys,
This is a question about UnityEdior script since I go around google and I can not find out the answer so I ask here, if my question content has existed somewhere please slightly point me and I will delete this question.
My problem is I don't understand how the GUIUtility.keyboardControl work. I create a textArea, I get the control Id of this textArea component, then I compare with the GUIUtility.keyboardControl while I edit text inside this testArea, and I saw that the control Id of my textarea is different from which I got from GUIUtility.keyboardControl (the control ID which I got from GUIUtility.keyboardControl always lesser than my textArea control Id 1 unit). As my expect it's must be equal. Do my understanding wrong?
(I take a look in the sources code of Unity but the GUIUtility.keyboardControl code has been move to native code? maybe ... so I can not find out any hint there)
This is my Test Code:
private void OnGui() {
m_textContent = GUILayout.TextArea(m_textContent);
int controlId = GUIUtility.GetControlID(FocusType.Keyboard);
m_evt = Event.current;
if (m_evt.isKey) {
Debug.Log("kb Control: " + GUIUtility.keyboardControl + "this id: " + id);
}
}
And I got something like: kb Control: 542 this id + 543
Thanks in advanced, Vince
Answer by Bunny83 · May 04, 2018 at 10:57 AM
Well the main problem here is that the ControlID that you generate is not the same that is generated inside the TextArea method,. When you call GetControlID 3 times in a row you get 3 different IDs back. That's the main point of the control IDs. The important thing is that the control ID generation is reset each time OnGUI is called so the same code will generate the same IDs.
The immediate mode GUI does not have "controls" or "components" in the sense of objects. The "control methods" like TextArea just handle events immediately. So if it's called during a repaint event it will actually render a text input field ad hoc. Have a look at the GUILayout.TextArea method. Inside DoTextField it "generates" a control ID for this control. You can't really access or aquire the control ID as it's only used internally. The reason why we actually have access to "GUIUtility.keyboardControl" is to implement your own controls.
The TextArea is rather complicated since it actually uses a state object, but only a text editor object. It's easier to understand how GUI controls work when you look at a simpler example like the RepeatButton for example. If you want to know more about the IMGUI system, have a look at my GUI crashcourse.
The intended way to identify a certain control is to use GUI.SetNextControlName and then use GUI.GetNameOfFocusedControl to determine which control has the focus. You can also use GUI.FocusControl to focus a named control.
First of all, tks for the clear explanation, Bunny. every time u answer a question, I'm so sure I will able to get more knowledge. ^^
When you call GetControlID 3 times in a row you get 3 different IDs back.
The important thing is that the control ID generation is reset each time OnGUI is called so the same code will generate the same IDs.
Now I understood, I'll never be able to get the exact control ID of my TextArea. In my Imagination of "ID", it has to absolutely, but after I understood what it's done, It's made me think that the control ID is so relatively. ~_~
The reason why we actually have access to "GUIUtility.keyboardControl" is to implement your own controls.
Yes, I try to customize a TextArea with onValueChange event. That's the reason why I want to get the ID of TextArea. And tks for the hint that you gave me. It helps a lot.
Well a quick an dirty "on value changed" check could be done like this:
string tmp = GUILayout.TextArea(m_textContent);
if (tmp != m_textContent)
{
m_textContent = tmp;
// changed, yeay ^^
}
Though it's possible to "guess" the right controlID by allocating your own just before the actual control and assume the control gets the next one. This however does not necessarily work in all cases since there are different GetControlID overloads which take in "hints". Also the implementation could change so the IDs might not be generated in order
Tks Bunny.
$$anonymous$$y idea from the beginning is custom a text editor that it's can catch the event when the key is down, and call some check there, then invoke the on value change callback :) but I think with my understanding of unity editor now, the dirty way is the best fit for me T__T, custom a text editor is still out of my reaching. :( swim$$anonymous$$g in unity editor code is so interesting lol.
Your answer
Follow this Question
Related Questions
serializedObject with EditorGUILayout.Popup in C# 1 Answer
EditorWindow: Use toggle to disable/enable other controls? 1 Answer
How to get proper layout for an objectfield 1 Answer
TextArea tab width 0 Answers
Is there a way to change the text size for a Vector3 PropertyField in a custom Inspector? 0 Answers