So I have a set of windows in my game that represent different menus (mission journal, inventory, etc…)
I have a function which toggles their visibility and causes them to be brought to the front of the screen. This all works excellent when I use the GUI button to call the function. However, if I use a keybind to call the function - the newly opened window is not properly brought to the screen.
The bizarre part is that the order is fixed as soon as I click anywhere on the screen (not necessarily on top of the windows - anywhere at all). As if the “GUI.BringWindowToFront (_myWinID);” event only fires during mouse events.
Here is a bit of the code.
// Code in my HUD - button opens the Journal and brings it to the front of the screen properly
if (EUILayout.ButtonWShadow("View Journal")){
Journal.Instance.toggleVisibility();
}
//Code in my Journal class, I've tried placing this in Update as well as OnGUI - in both cases it opens the window fine, but does not bring it to the front of the screen.
if (Input.GetButtonDown ("Journal")) {
toggleVisibility ();
}
// The function actually being called
public void toggleVisibility(){
if (_bGUIOpen){
_bGUIOpen = false;
} else {
_bGUIOpen = true;
_bRecentlyOpened = true;
}
}
// _bGUIOpen just causes the OnGUI even to move forward and actually do stuff. bRecentlyOpened is used as follows:
if (_bRecentlyOpened) {
_bRecentlyOpened = false;
GUI.BringWindowToFront (_myWinID);
}
The really strange part is that I’ve tried commenting out _bRecentlyOpened = false, causing the OnGUI loop to cal GUI.BringWindowToFront(id) every single time and yet it still isn’t brought to the front of the screen. Debug logging shows that _bRecentlyOpened is being set properly from the keybind as well as the gui button, GUI.BringWindowToFront() just is not working at all until I start to use the mouse again.
Anyone have any thoughts on this? Any way to force a GUI.BringWindowToFront would be much appreciated!
Hey, did you manage to solve this issue? I noticed the exact thing happening to my GUI recently. The GUI.BringWindowToFront command refuses to work with the keybinds.
Nope, sorry. Never got a response - tried a few more things but none of them worked.
You can even force the focus of a window, but I can’t seem to find a way to bring it to the front without mouse input.
I did find one way around it, but it’s so hacky that I’m not going to implement it until our game is approaching ship date and BringWindowToFront is still bugged.
Basically what you could do is implement a dynamic depth system and handle the window order yourself internally. Keep a sorted list/array if open windows and what order they should be in (I already do this for another reason, we have “escape” close windows in reverse order to when they were opened), and assign a GUI.depth to each window based on that list.
So basically you would have
GUI.Depth Range 0 [ Stuff that should appear on top of windows]
GUI.Depth Range 1 [ Windows ]
GUI.Depth Range 2 [ Stuff that should appear below windows]
You would grow/shrink these depth ranges dynamically as needed, and sort range 1 as needed as well. So it could look something like
GUI.Depth = 0 // Stuff on top of windows
GUI.Depth = 1 // top window
GUI.Depth = 2 // second window
GUI.Depth = 3 // third window
GUI.Depth = 4 // Stuff below window
It’s an ugly solution though, so we are holding out for a fix for now.
I’ve tried that. The window will get focus but will somehow not be brought to front. Still very baffled why this is suddenly happening. Just to clarify again, this issue seems to be only happening to keybinds. Getting the most recent window to appear on top is not a problem if I were to click on the related button instead.
There doesn’t appear to be an entry in the bug database for this. If you have a reproducing case you could share then the QA team would be glad to receive it (menu: Help > Report A Bug).
var windowRect0 : Rect = Rect (20, 20, 120, 50);
var windowRect1 : Rect = Rect (20, 100, 120, 50);
var windowRect2 : Rect = Rect (20, 180, 120, 50);
var keyPressed = -1;
function OnGUI () {
// Register the window. We create two windows that use the same function
// Notice that their IDs differ
windowRect0 = GUI.Window (0, windowRect0, DoMyWindow, "My Window");
windowRect1 = GUI.Window (1, windowRect1, DoMyWindow, "My Window");
windowRect2 = GUI.Window (2, windowRect2, DoMyWindow, "My Window");
if (keyPressed == 0) {
GUI.BringWindowToBack(1) ;
GUI.BringWindowToBack(2) ;
GUI.BringWindowToFront(0) ;
keyPressed = -1;
GUI.FocusWindow(0);
}
if (keyPressed == 1) {
GUI.BringWindowToBack(0) ;
GUI.BringWindowToBack(2) ;
GUI.BringWindowToFront(1) ;
keyPressed = -1;
GUI.FocusWindow(1);
}
if (keyPressed == 2) {
GUI.BringWindowToBack(0) ;
GUI.BringWindowToBack(1) ;
GUI.BringWindowToFront(2) ;
keyPressed = -1;
GUI.FocusWindow(2);
}
}
// Make the contents of the window
function DoMyWindow (windowID : int) {
if (GUI.Button (Rect (10,20,100,20), "Hello World" + windowID))
print ("Got a click in window " + windowID);
// Make the windows be draggable.
GUI.DragWindow (Rect (0,0,10000,10000));
}
function Update () {
if (Input.GetKeyDown(KeyCode.Keypad0)){
keyPressed = 0;
}
if (Input.GetKeyDown(KeyCode.Keypad1)){
keyPressed = 1;
}
if (Input.GetKeyDown(KeyCode.Keypad2)){
keyPressed = 2;
}
}
What most people forget is OnGUI loops , so you are continually sending the command to draw the window. So the order you call them in the OnGUI creates them in that order, and natuarally the later the draw, that one is on TOP! So if you trigger your window by a button, but set a flag to draw it (ie if (GUI.Button(XXX) windowon = true)
So your GUI loops, and the draw occurs, then you need to decide who is on top, and why (use an array or other, Last button touched, etc.)
Overall is complicated, when you have many possible windows that can be up at one time.
So the control of the draw with an array of current open windows, add to the array in the order they are clicked.
Then you can get really fancy and when the users touch one, you can bring it to the front (with a hidden button in the top area)! weeeeee