Search Unity

GetControlID

Discussion in 'Immediate Mode GUI (IMGUI)' started by cybernoid, Nov 15, 2010.

  1. cybernoid

    cybernoid

    Joined:
    Nov 15, 2010
    Posts:
    27
    I am sure I am not the only one who thinks that the function GUIUtility.GetControlID() is not very well explained in the Unity documentation.

    I understand the overall concept of an IMGUI but am not reliably sure how these ID's are being generated in Unity and the exact reasons. As far as I can tell the inbuilt controls user overloads for GetControlID that use a combination of a predefined hash for a specific control type, the focus type of a control (which I don't quite understand the reason for), and a controls screen space rectangle.

    In a fairly large project we have tried to use predefined ID's but then had issues I presume caused by them clashing with the automatically generated ones in the Unity default controls so we are attempting to switch to - again in the Unity documentation it doesn't say _always_ use GetControlID - in fact the initial examples specify predefined integer controlID's so this is confusing.

    Also in terms of the controlID generation I am not sure on its reliable behaviour dependent on the call path of GUI functions - although I understand the need to keep the call path relatively static to some degree.

    Trying to avoid the dreaded 'get control position in group' error message on a large project with multiple junior programmers is a bit of a headache to be honest - especially as these things are again not seemingly well documented - and unfortunately gives the ability for such problems to knock out the whole of the UI.

    I understand that possibly for the first layout event pass the Unity GUI internals are building a dictionary that is used in a later pass that requires the passes to stick to the same call path and thus generate the correct controlID's. But again its very hard to be sure that my limited understanding of the system is correct from the existing documentation.

    Any comments to help further my understanding of this are welcome thanks!
     
    IgorAherne likes this.
  2. AngryAnt

    AngryAnt

    Keyboard Operator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    Here's a quick (untested) example of writing a custom GUILayout control using GetControlID and GetRect:
    CustomGUILayout.cs
    Code (csharp):
    1. using UnityEngine;
    2.  
    3. public class CustomGUILayout
    4. {
    5.     public static bool MyFocusControl (Texture2D texture, params GUILayoutOption[] options)
    6.     {
    7.         int id = GUIUtility.GetControlID ();
    8.         Color color = GUI.color;
    9.  
    10.         GUI.color = GUIUtility.hotControl == id ? Color.green : Color.red;
    11.         Rect rect = GUILayoutUtility.GetRect (texture.width, texture.height, options);
    12.  
    13.         switch (Event.current.type)
    14.         {
    15.             case EventType.MouseDown:
    16.                 if (rect.Contains (Event.current.mousePosition))
    17.                 {
    18.                     GUIUtility.hotControl = id;
    19.                     Event.current.Use ();
    20.                 }
    21.             break;
    22.             case EventType.Repaint:
    23.                 GUI.DrawTexture (rect, texture);
    24.             break;
    25.         }
    26.  
    27.         GUI.color = color;
    28.  
    29.         return GUIUtility.hotControl == id;
    30.     }
    31. }
    32.  
    33. /*
    34.     Usage:
    35.    
    36.     bool isActive = CustomGUILayout.MyFocusControl (myTexture);
    37.     GUILayout.Label (string.Format ("The custom control is {0}", isActive ? "active" : "inactive"));
    38. */
     
  3. ZoltanErdokovy

    ZoltanErdokovy

    Joined:
    Aug 23, 2012
    Posts:
    102
    It doesn't seem to get EventType.MouseDown for me, only repaint. I'm trying to make it
    work in an EditorWindow. What am I missing?
     
  4. ParkyRander

    ParkyRander

    Joined:
    Jun 1, 2014
    Posts:
    8
    Could try
    Code (CSharp):
    1. switch (Event.current.GetTypeForControl(id))