Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Demigiant · Sep 30, 2012 at 11:59 AM · guiunityeditor

Get ControlID of simple GUI button

I simply need to get the controlID of a GUI/GUILayout.Button, without forcefully assigning it, so that I can compare it with the GUIUtility.hotControl value.

Clearly Unity's GUI keeps a controlID for each GUI element, so this should be a simple task, but I can't find a solution. Also, consider that I need this in an Editor panel, so I have access to Editor classes.

Thanks for any help.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

4 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by franky303 · Sep 30, 2012 at 02:22 PM

Rect bounds .... is the rect of the button ....

 int controlID = GUIUtility.GetControlID(bounds.GetHashCode(), FocusType.Passive);

this is what i'm using, also for comparing against GUIUtility.hotControl and it works.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Demigiant · Sep 30, 2012 at 03:24 PM 0
Share

Thanks, but that doesn't work for me. I should also note that I'm using GUILayout in a strange way (via a framework which wraps layouts as actions), and the usual trick (calling GetControlID(...) $$anonymous$$us 1 after an element to get its controlID) doesn't work either.

avatar image Jeff-Kesselman · Nov 12, 2013 at 12:55 AM 0
Share

Yup doesn't work for me, either.

The only solution I have found, which is pretty nasty, is to get a dummy ID just before I draw the component and then assume the component's id is dummyID +1

avatar image
0

Answer by franky303 · Sep 30, 2012 at 02:37 PM

You might be interested in this piece of code. It solves a bug when using overlapping buttons (unity usually fires the button click event for the overlapped button, not for the topmost button), also works for touch devices and solves the problem when using scrollviews with buttons, too (it will only fire on button click, not on dragging the scroll view):

 /* 
  * 
  * **** GUIButton CLASS ****
  * 
  * this versions sends only events to the topmost button ...
  * 
  * 
  * Fixes the bugs from the original GUI.Button function
  * Based on the script from Joe Strout: 
  * http://forum.unity3d.com/threads/96563-corrected-GUI.Button-code-%28works-properly-with-layered-controls%29?p=629284#post629284
  * 
  * 
  * The difference in this script is that it will only fire events (click and rollover!)
  * for the topmost button when using overlapping buttons inside the same GUI.depth! 
  * Therefore the script finds the topmost button during the layout process, so it 
  * can decide which button REALLY has been clicked.
  * 
  * Benefits:
  * 1. The script will only hover the topmost button!
  *    (doesn't matter wheter the topmost button is defined via GUI.depth or via drawing order!)
  * 2. The script will only send events to the topmost button (as opposed to Joe's original script)
  * 3. The script works for overlapping buttons inside same GUI.depth levels,
  *    as well as for overlapping buttons using different GUI.depth values
  * 4. The script also works when overlapping buttons over buttons inside scrollviews, etc.
  * 
  * Usage:  just like GUI.Button() ... for example:
  * 
  *     if ( GUIButton.Button(new Rect(0,0,100,100), "button_caption", GUI.skin.customStyles[0]) )
  *    {
  *         Debug.Log( "Button clicked ..." );
  *    }
  *
  * 
  *
  * Original script (c) by Joe Strout!
  * 
  * Code changes:
  * Copyright (c) 2012-2013 by Frank Baumgartner, Baumgartner New Media GmbH, fb@b-nm.at
  *
  * 
  * */
 
 
 using UnityEngine;
 using System.Collections;
 
 public static class GUIButton 
 {
     private static int highestDepthID = 0;
     private static EventType lastEventType = EventType.Layout;
 
     private static int frame = 0;
     private static int lastEventFrame = 0;
     
     public    static bool noButtonActive = false;
     public    static Vector2 lastClickPos = Vector2.zero;
     
     public     static int lastDownButtonHash = 0;
     
     
     public static bool Button(Rect bounds, string caption2, GUIStyle btnStyle = null ) 
     {
         string caption = "";
 
         // this made problems when adding/removing controls during UI's: 
         // int controlID = GUIUtility.GetControlID( bounds.GetHashCode(), FocusType.Passive );
 
         // this one works also with dynamic GUI's !
         int controlID = GUIUtility.GetControlID( FocusType.Passive );
 
         bool isMouseOver = bounds.Contains(Event.current.mousePosition);
         int depth = (1000 - GUI.depth) * 1000 + controlID;
         if ( isMouseOver && depth > highestDepthID ) highestDepthID = depth;
         bool isTopmostMouseOver = (highestDepthID == depth);        
         bool wasDragging = TouchDragDetector.isTouchDragging();
         if ( isMouseOver ) noButtonActive = false;
 
 #if (UNITY_IPHONE || UNITY_ANDROID) && !UNITY_EDITOR
         bool paintMouseOver = isTopmostMouseOver && (Input.touchCount > 0) && !wasDragging;
 #else
         bool paintMouseOver = isTopmostMouseOver;
 #endif
 
         if ( btnStyle == null ) 
         {
             btnStyle = GUI.skin.FindStyle("button");
         }
 
         if ( Event.current.type == EventType.Layout && lastEventType != EventType.Layout )
         {
             highestDepthID = 0;
             frame++;
             noButtonActive = true;
         }
         lastEventType = Event.current.type;
             
         if ( Event.current.type == EventType.Repaint ) 
         {
             bool isDown = (GUIUtility.hotControl == controlID);
 
             if ( caption == null || caption == "" )
             {
                 // optimized: only 1 drawcall instead of two!
                 if ( paintMouseOver && btnStyle.hover != null && btnStyle.hover.background != null )
                 {
                       GUI.DrawTexture( bounds, btnStyle.hover.background, ScaleMode.StretchToFill );
                 }
                 else if ( isDown && btnStyle.active != null && btnStyle.active.background != null )
                 {
                       GUI.DrawTexture( bounds, btnStyle.active.background, ScaleMode.StretchToFill );
                 }
                 else if ( btnStyle.normal != null && btnStyle.normal.background != null )
                 {
                       GUI.DrawTexture( bounds, btnStyle.normal.background, ScaleMode.StretchToFill );
                 }
             }
             else
             {
                 // Works but is slow: always creates 2 drawcalls: (1 bg and 1 for text)
                 btnStyle.Draw(bounds, new GUIContent(caption), paintMouseOver, isDown, false, false);
             }
         }
         
         // Workaround:
         // ignore duplicate mouseUp events. These can occur when running
         // unity editor with unity remote on iOS ... (anybody knows WHY?)
 //        if ( frame <= (1+lastEventFrame) ) return false;
         if ( frame <= (10+lastEventFrame) ) return false;        // increased to 10 due to double clicks on ipad 3 ...
 
         switch ( Event.current.GetTypeForControl(controlID) ) 
         {
             case EventType.mouseDown:
             { 
                 // Debug.Log ("mouseclick: topmost=" + isTopmostMouseOver + " wasDragging=" + wasDragging + " controlID=" + controlID + " caption=" + caption );
                 if ( isTopmostMouseOver && !wasDragging )
                 {
                     GUIUtility.hotControl = controlID;
                 }
                 break;
             }
 
             case EventType.mouseUp:
             {
                 GUIUtility.hotControl = 0;
                 if ( isTopmostMouseOver && !wasDragging )
                 {
                     lastClickPos.x = Input.mousePosition.x;
                     lastClickPos.y = Input.mousePosition.y;
                     lastEventFrame = frame;
 
                     // log events for statistics ...
                     StaticActivityLogger.logButtonEvent();
                     return true;
                 }
                 break;
             }
         }
         return false;
     }
 }
 
 
 
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Demigiant · Sep 30, 2012 at 03:27 PM 0
Share

Very interesting, thanks for sharing :) I use GUI methods only in the Editor (where there are no overlapping issues), and usually go for a sprite approach while in-game, to get better performance, but I'm gonna check it out.

avatar image franky303 · Nov 12, 2013 at 06:56 AM 0
Share

i've just updated the code. this version is also working with dynamic GUI's (i.e. the number of buttons is changing during the app in response to user interaction).

avatar image
0

Answer by Jeff-Kesselman · Nov 12, 2013 at 01:00 AM

This is the only solution I've found that works...

http://answers.unity3d.com/questions/348582/how-can-i-get-the-last-assigned-controlid.html

Its a nasty use of side effects and not generally recommended good technique, but it does seem to work with the current version of Unity. Be aware that you must do the ID fetch just before the actual draw of the button or other component.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by TinkerinThinker · Dec 16, 2013 at 05:58 PM

I think that since you're attempting to write an Editor script, you want EditorGUIUtility.GetControlID instead.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

13 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

my ui score only works in editor but not in build version of the game 0 Answers

Converting from EditorWindow to runnable window 1 Answer

How do I display a texture in the scene view? 1 Answer

how to translate(Bengali) Gui, tools, tabs and other things 0 Answers

Align text into PropertyField 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges