- Home /
2 Buttons overlap problem
I have a frame when I clicked on sell button, the DisplayQuantity frame will shown. My problem now is that when my mouse hover to the quantity frame sell button the display frmae button will also hover, the DisplayQuantity frame was overlap on display frame, so when mouse hover will cause 2 buttons which almost at same positions have the hover effect. How can I solve this? How to force prevent user clicking the display frame button when the displayQuantity frame was visible.
void display(){
GUI.BeginGroup (new Rect (70, 55, 650, 510));{
GUI.Label (new Rect (x, y + (index * 190), 296, 172), "", "item_label");
GUI.Label (new Rect (x + 5, y + (index * 190) + 7, 128, 157), "", "image_label");
GUI.DrawTexture (new Rect (x + 40, y + 45, 48, 61), itemPic);
GUI.Button (new Rect (x + 135, y + 130 + (index * 190), 76, 31), "", "use_btn");
if (GUI.Button (new Rect (x + 215 + (index * 310), y + 130, 76, 31), "", "sell_btn")) {
displayQuantity = true;
}
GUI.EndGroup ();
}
}
So when sell button was clicked I will display another frame :
void DisplayQuantity ()
{
GUI.skin = this.quantity;
GUI.BeginGroup (new Rect (280, 250, 300, 150));
{
GUI.Box (new Rect (0, 0, 300, 150),"", "qbgImage");
// Close button
if (GUI.Button (new Rect (270, 10, 21, 22), "", "close_btn_q")) {
displayQuantity = false;
}
GUI.Label (new Rect (160, 50, 80, 27), quan);
GUI.Label (new Rect (10, 10, 104, 131), "", "quantity_frame");
if (GUI.Button (new Rect (250, 50, 30, 27), "", "increase_btn")) {
if ((Convert.ToInt32 (quan) + 1) < 99) {
quan = (Convert.ToInt32 (quan) + 1).ToString ();
}
}
if (GUI.Button (new Rect (120, 50, 30, 27), "", "decrease_btn")) {
if ((Convert.ToInt32 (quan) - 1) > 0) {
quan = (Convert.ToInt32 (quan) - 1).ToString ();
}
}
if (GUI.Button (new Rect (220, 90, 64, 27), "", "sell_btn")) {
}
}
GUI.EndGroup ();
}
If you want to get that to work, you're going to have to take some time to read and learn.
I recommend reading about GUI.depth here:
http://unity3d.com/support/documentation/ScriptReference/GUI-depth.html
(please try reading some documentation before asking people to write code for you)
If you go to the link in my answer, you'll see some other links discussing how to draw overlapping GUI controls.
To be quite honest, I think it's going to be a little too advanced for you right now. I STRONGLY suggest that you simply draw your buttons so they don't overlap.
Another major difficulty is the fact that we speak different languages.
I really want to help, but we're not getting anywhere. At all.
I agree with jahroy that this question doesn't seem very easy to answer, probably in part due to communication barriers. So ins$$anonymous$$d of adding another answer, I'm adding a comment:
The described problem is a classic case of "GUI click-through". If you search for that, you can find quite a few questions and posts about other people experiencing this, with popup windows in particular.
It is caused by a flaw in GUI.Button that causes it to incorrectly handle a mouseDown event that should've been reserved for another control. There is a corrected version of the button available here:
Copy the function goodButton to your script, and call that ins$$anonymous$$d of the standard GUI.Button. The corrected version handles click-through correctly.
Yes, after reading the overlap button problem,trying using the window also cant works sigh. anyway Thanks for your help.
Answer by franky303 · Sep 23, 2012 at 10:57 AM
Hello, i've used JoeStrout's script from this thread http://forum.unity3d.com/threads/96563-corrected-GUI.Button-code-(works-properly-with-layered-controls) and extended it to only fire events to the topmost button. It also ignores events resulting from being dragged over, so it works together with scrollViews on mobile devices. You might want to check this out:
/*
*
* **** 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_action", GUI.skin.customStyles[0]) )
* {
* Debug.Log( "Button clicked ..." );
* }
*
*
*
* Original script (c) by Joe Strout!
*
* Code changes:
* Copyright (c) 2012 by Frank Baumgartner, Baumgartner New Media GmbH, fb@b-nm.at
*
*
* */
using UnityEngine;
using System.Collections;
public class GUIButton
{
private static int highestDepthID = 0;
private static Vector2 touchBeganPosition = Vector2.zero;
private static EventType lastEventType = EventType.Layout;
private static bool wasDragging = false;
private static int frame = 0;
private static int lastEventFrame = 0;
public static bool Button(Rect bounds, string caption, GUIStyle btnStyle = null )
{
int controlID = GUIUtility.GetControlID(bounds.GetHashCode(), 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);
#if (UNITY_IPHONE || UNITY_ANDROID) && !UNITY_EDITOR
bool paintMouseOver = isTopmostMouseOver && (Input.touchCount > 0);
#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++;
}
lastEventType = Event.current.type;
if ( Event.current.type == EventType.Repaint )
{
bool isDown = (GUIUtility.hotControl == controlID);
btnStyle.Draw(bounds, new GUIContent(caption), paintMouseOver, isDown, false, false);
}
#if (UNITY_IPHONE || UNITY_ANDROID)
if ( Input.touchCount > 0 )
{
Touch touch = Input.GetTouch(0);
if ( touch.phase == TouchPhase.Began )
{
touchBeganPosition = touch.position;
wasDragging = true;
}
else if ( touch.phase == TouchPhase.Ended &&
( (Mathf.Abs(touch.position.x - touchBeganPosition.x) > 15) ||
(Mathf.Abs(touch.position.y - touchBeganPosition.y) > 15) )
)
{
wasDragging = true;
}
else
{
wasDragging = false;
}
}
else if ( Event.current.type == EventType.Repaint )
{
wasDragging = false;
}
#endif
// 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;
switch ( Event.current.GetTypeForControl(controlID) )
{
case EventType.mouseDown:
{
if ( isTopmostMouseOver && !wasDragging )
{
GUIUtility.hotControl = controlID;
}
break;
}
case EventType.mouseUp:
{
if ( isTopmostMouseOver && !wasDragging )
{
GUIUtility.hotControl = 0;
lastEventFrame = frame;
return true;
}
break;
}
}
return false;
}
}
Answer by jahroy · Oct 24, 2011 at 07:18 PM
One approach would be to use invisible Labels to explicitly control which tooltips appear in which areas...
Here's a post with a bunch of chatter about drawing GUI controls on top of each other:
http://answers.unity3d.com/questions/59898/how-to-draw-gui-controls-on-top-of-each-other.html
Unfortunately it does not discuss tooltips...
Thanks, but I want to Label visible there any other method?
Yes, you make visible labels as well as invisible ones.
Sorry I not very understand what did you mean make visible labels as well as invisible ones?
Visible as in the opposite of invisible. You can make both.
I thought the original question was about tooltips...
At that point, the suggestion was to use a normal button to display your button and an invisible label (with a slightly different rectangle) to control when the tooltips appear.
I think a good approach to your current problem would be to draw the buttons so they don't overlap.
I know this isn't what your're looking for, but I would get rid of all those hard coded numbers (and replace them with variables).
I've never seen so many numbers in code....
If all those numbers were variables, you could tweak them in the Inspector and get everything just right.
Answer by tcz8 · May 04, 2019 at 07:39 PM
Hey @franky303 just tried that code and I'm somehow still struggling with the same issue.
I have an autocomplete text field that display its autocomplete suggestions over a MultiColumnHeader and a ScrollView filled with buttons. All buttons in the scrollview and the autocomplete code have been replaced by your code. Any idea what could be wrong? Do I have to replace ALL buttons in the entire editor window for this to work or only overlapping ones?
OnGUI draws the controls in this order: ScrollView, MultiColumnHeader and then the Autocomplete.
The Autocomplete suggestions are drawn as follow:
if (suggestions.Count > 0) {
GUI.BeginGroup(area, new GUIStyle("CN Box"));
DrawAutocompleteSuggestions();
GUI.EndGroup();
}
And DrawAutocompleteSuggestions() does this:
static void DrawAutocompleteSuggestions() {
for (int i = 0; i < cnt; i++)
{
Debug.Log("Draw button #" + i);
// if (GUI.Button(itemRect, m_CacheCheckList[i], GamePlanEditor.gamePlanWindow.style_AutoCompleteResults)) // TODO: add style selection to parameters (overloads too)
if (GUIExtentions.Button(itemRect, m_CacheCheckList[i], GamePlanEditor.gamePlanWindow.style_AutoCompleteResults))
{
Debug.Log("BUTTON CLICKED!!!");
selectedString = m_CacheCheckList[i];
GUI.changed = true;
GUI.FocusControl(""); // force update
Event.current.Use();
}
itemRect.y += singleItemHeight;
}
}
FYI here is a slighty modifed version were I renamed the input parameters to match unity's api and I added overloads to allow specifying the content using a string, texture or GUIContent directly. I also added overloads that uses the AutoLayout mode (like GUILayout) instead of taking a rect;
/*
*
* **** 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_action", GUI.skin.customStyles[0]) )
* {
* Debug.Log( "Button clicked ..." );
* }
*
*
*
* Original script (c) by Joe Strout!
*
* Code changes:
* Copyright (c) 2012 by Frank Baumgartner, Baumgartner New Media GmbH, fb@b-nm.at
*
* Code changes:
* 2019 by Frédéric Defoy for NWS
*
*
* */
// using UnityEngine;
// using System.Collections;
public class GUIExtentions
{
private static int highestDepthID = 0;
private static Vector2 touchBeganPosition = Vector2.zero;
private static EventType lastEventType = EventType.Layout;
private static bool wasDragging = false;
private static int frame = 0;
private static int lastEventFrame = 0;
public static bool Button(string text, params GUILayoutOption[] options) {
GUIContent content = new GUIContent(text);
return Button(GUILayoutUtility.GetRect(content, GUI.skin.button, options), content, GUI.skin.button);
}
public static bool Button(string text, GUIStyle style = null, params GUILayoutOption[] options) {
GUIContent content = new GUIContent(text);
return Button(GUILayoutUtility.GetRect(content, style, options), content, style);
}
public static bool Button(Texture image, params GUILayoutOption[] options) {
GUIContent content = new GUIContent(image);
return Button(GUILayoutUtility.GetRect(content, GUI.skin.button, options), content, GUI.skin.button);
}
public static bool Button(Texture image, GUIStyle style = null, params GUILayoutOption[] options) {
GUIContent content = new GUIContent(image);
return Button(GUILayoutUtility.GetRect(content, style, options), content, style);
}
public static bool Button(GUIContent content, params GUILayoutOption[] options) {
return Button(GUILayoutUtility.GetRect(content, GUI.skin.button, options), content, GUI.skin.button);
}
public static bool Button(GUIContent content, GUIStyle style = null, params GUILayoutOption[] options) {
return Button(GUILayoutUtility.GetRect(content, style, options), content, style);
}
public static bool Button(Rect bounds, string text, GUIStyle style = null ) {
GUIContent content = new GUIContent(text);
return Button(bounds, content, style);
}
public static bool Button(Rect bounds, Texture image, GUIStyle style = null ) {
GUIContent content = new GUIContent(image);
return Button(bounds, content, style);
}
static bool Button(Rect bounds, GUIContent content, GUIStyle style = null )
{
int controlID = GUIUtility.GetControlID(bounds.GetHashCode(), 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);
#if (UNITY_IPHONE || UNITY_ANDROID) && !UNITY_EDITOR
bool paintMouseOver = isTopmostMouseOver && (Input.touchCount > 0);
#else
bool paintMouseOver = isTopmostMouseOver;
#endif
if ( style == null )
{
style = GUI.skin.FindStyle("button");
}
if ( Event.current.type == EventType.Layout && lastEventType != EventType.Layout )
{
highestDepthID = 0;
frame++;
}
lastEventType = Event.current.type;
if ( Event.current.type == EventType.Repaint )
{
bool isDown = (GUIUtility.hotControl == controlID);
style.Draw(bounds, content, paintMouseOver, isDown, false, false);
}
#if (UNITY_IPHONE || UNITY_ANDROID)
if ( Input.touchCount > 0 )
{
Touch touch = Input.GetTouch(0);
if ( touch.phase == TouchPhase.Began )
{
touchBeganPosition = touch.position;
wasDragging = true;
}
else if ( touch.phase == TouchPhase.Ended &&
( (Mathf.Abs(touch.position.x - touchBeganPosition.x) > 15) ||
(Mathf.Abs(touch.position.y - touchBeganPosition.y) > 15) )
)
{
wasDragging = true;
}
else
{
wasDragging = false;
}
}
else if ( Event.current.type == EventType.Repaint )
{
wasDragging = false;
}
#endif
// 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;
switch ( Event.current.GetTypeForControl(controlID) )
{
case EventType.MouseDown:
{
if ( isTopmostMouseOver && !wasDragging )
{
GUIUtility.hotControl = controlID;
}
break;
}
case EventType.MouseUp:
{
if ( isTopmostMouseOver && !wasDragging )
{
GUIUtility.hotControl = 0;
lastEventFrame = frame;
return true;
}
break;
}
}
return false;
}
}
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
A node in a childnode? 1 Answer
Distribute terrain in zones 3 Answers
Unity: C#: Eyes look at mouse: HELP!! 3 Answers