Jump to content

GUIStyles question


Recommended Posts

Good day, I have a question with GUIStyles and why the changes I make to them do not seem to be sticking.

First, I create my style during the Start() method of the Flight scene as so:


AGXSkin = (GUISkin)MonoBehaviour.Instantiate(HighLogic.Skin);
AGXBtnStyle = new GUIStyle(AGXSkin.button);
//AGXBtnStyle.Variables get set here.

I never set any part of the AGXBtnStyle again, it is all in the Start() method.

This results in a window that looks like this most of the time (bottom window):

AGExtQuickStart2.jpg

However, sometimes exterior factors seem to affect my GUIstyle, notably bringing up the in-game ESC menu causes this (top window):

35ip477.jpg

Note the black box that seems to have appeared (also visible in the lower box covering the Window Title text) and while the second screen shot isn't clear, the font itself has changed slightly and moved upwards a few pixels on the button.

Now, the first two lines in the Start code are both supposed to make stand alone copies of the Style that, in my understanding, would prevent outside forces from changing my style. This is not what is happening as simply bringing up the in-game ESC menu causes my GUIStyle to change somehow.

I've bashed my head against this for quite a while now and gotten no where, does anyone have any ideas on what causes this, or what I am missing in my understanding of GUIStyles?

D.

Link to comment
Share on other sites

Is this used inside GUILayout or inside GUI?

Those buttons are on top of each other as soon as it goes wrong - right?

That indicates it's GUI - GUI needs strict positioning..

Could it be, that these buttons are positioned by GUI-functions and somehow lose theire position Rect values?

Just guessing..

would need more insight to debug..

Link to comment
Share on other sites

The only differences I see between how you approach it and how I have approached it with Pilot Assistant are:

1) I build the GUISkin/GUIStyles in the first draw call. I seem to recall it throwing errors when I tried to do it in Start, never bothered to figure out why. I assume that's not an issue here since things seem to be working...

2) I skip the need to assign GUIStyles to every GUI object and just set GUI.Skin to my saved GUISkin before anything else in the draw calls. That way you can be sure you aren't missing any, and only need to specify the style where it doesn't match (eg. drawing a box as a button). When I had this issue it was all down to one or two objects that didn't get a style attached.

PS

Would you mind specifying some relevant lines in Github. Your flight scene code is somewhat long and I'm having some difficulty matching sections of code to individual windows...

I would check TriggerAu's code for doing this, as it seems to work fine

It's the same base method as used by TriggerAu

Edited by Crzyrndm
Link to comment
Share on other sites

Ya, my code's kind of gotten out of control at this point.

And I use GUI, not GUILayout.

So, code reference:

Start() method where I copy the skin and styles.

FlightWindow() method that draws the window in question.

The "KeySet1" button.

GUI.BeginScrollWindow that is the smaller, darker, rectangle behind the buttons that sticks out to the right.

@Button positioning: Button position is fine and does not move. When this issue occurs, the text on the button moves up a few pixels relative the button the text is drawn by. The font also changes slightly for some reason. (I'll try to get some zoomed in pictures to show this when I can.) IE: The KeySet1 button stays still on the screen while the "KeySet1" text itself moves on the screen a few pixels. If I was not assigning the alignment every frame the window is drawn, I would think my alignment value is being changed somehow from MiddleCenter to TopCenter.

@Using GUI.Skin: As I understand things, this is my problem. GUI.Skin and Highlogic.Skin are Static objects in KSP. Any changes made by any mod to these objects carry over to other mods using said objects. Therefore I'm jumping through all these hoops trying to make a GUISkin/Style that is totally separate from GUI.Skin (or Highlogic.Skin) that I can use exclusively for my mod because (I think) this issue is caused by other mods (or base KSP when the pause menu opens) modifying HighLogic.Skin on me.

@GUI.BeginScrollView: Digging into my code some more, part of my problem is that I can't figure out how to assign a style to GUI.BeginScrollView, these are the boxes that are appearing on top of everything. The BeginScrollWindow object only allows assigning styles for the scrollbars, not for the window itself. If I could figure this part out, it might be enough to mitigate what is going on that I could proceed.

I still feel like I'm grasping at straws here, my understanding of what I think GUIStyles do and what is actually happening are two very different things and I am open to any help you guys can give me.

D.

Edited by Diazo
Link to comment
Share on other sites

I think it's not your style, it is GUI

GUI is in CSS terms the "absolute" - GuyLayout is "relative"

if you have two buttons in vertical GUILayout, the will automatically be positioned propperly and the box height wll be increased to make them fit

GUI on the other hand, allways messures from the reference box by your Rect values..

if you diplay the button for example in an other box with other messurements, those carefully set RectValues are non-sense in that reference..

My suggestion might sound drastic at first, but if you don't have a special reason for using GUI, it might be worth it..

Replace all GUI with GUILayout and see what happens..

my gutt says, the problems will just be gone..

Only reason for GUI, is pixelperfect positioning - for example if you have two textures that need to be over each other and one rotates or so - for a gauge or something..

all other GUI "should" IMO be GuiLayout - less headache

If I had to guess, I'd say, the box that contains these button loses it's Rect Height- or Top-Value somehow - and that destroys your layout..

with GUILayout, this will never happen..

my 2 cents..

HTH

Link to comment
Share on other sites

But the button position is fine and not changing. It's the button text that is moving on the button. Hence why I'm trying to figure out GUIStyles, as I understand things the GUIStyle is what controls how the button text appears on the button.

D.

Link to comment
Share on other sites

Ya, my code's kind of gotten out of control at this point.

Heh.

@Using GUI.Skin: As I understand things, this is my problem. GUI.Skin and Highlogic.Skin are Static objects in KSP. Any changes made by any mod to these objects carry over to other mods using said objects. Therefore I'm jumping through all these hoops trying to make a GUISkin/Style that is totally separate from GUI.Skin (or Highlogic.Skin) that I can use exclusively for my mod because (I think) this issue is caused by other mods (or base KSP when the pause menu opens) modifying HighLogic.Skin on me.

GUI.Skin is the current default GUIStyles for each object that is to be drawn (which defaults to the Unity skin, and gets altered by KSP and mods as required). By setting GUI.Skin to be your saved defaults, you remove any chance of KSP/other mods from making changes that affect your GUI. After that, you only need to specify styles where the style to use isn't the default one. Things like the GUIStyle of a scrollview aren't an issue.

EDIT

Ok, that is wierd. The alignment setting should work just fine, but the text in both buttons appears to be using TopCenter, not MiddleCenter (I may have missed your issue the first time round...). The only thing I can think of is that it's trying to print multiple lines of text, is there any chance of a newline character being added to KeySetNamesFlight[int id]? I'm guessing not, so I'm totally stumped as to why this didn't work (https://github.com/SirDiazo/AGExt/blob/master/AGExt/Flight.cs#L1627)

PS

Drawing the right button and then the left button? Are you trying to confuse yourself? :P

Edited by Crzyrndm
Link to comment
Share on other sites

Okay, to detail what is going on:

r5W9t12.png

Only difference between left and right is hitting the ESC key.

Left: As desired

Right: Font on button changes and moves upwards, black rectangle (GUI.ScrollView) shows across the top, just below the Actions title and across the Queued Actions text.

@Sarbian: I've never used OnGUi() for any of my mods and this has been the only issue I've been unable to resolve with doing GUI stuff.

@Crzyrndm: How does that work? When I look at UnityEngine.GUI.SKin in the object browser it is a static, so if I do something like

UnityEngine.GUI.Skin.button.normal.textcolor = color.red;

am I not turning the text on all buttons across all mods that use GUI.Skin.button red, not just my own mod?

As I don't want to do that and want my GUI settings exclusive to my mod only, I'm posting this thread trying to figure out how to do that.

D.

Link to comment
Share on other sites

If you don't want to affect anyone else, just remember what the skin was and set it back after you're done.

GUISkin orginalSKin = (GUISkin)MonoBehaviour.Instantiate(GUI.Skin);;
Gui.Skin = MySkin;
// Your GUI Stuff
Gui.Skin = originalSkin;

But really, that doesn't help other people IMO. KSP itself makes changes to GUI.Skin when certain windows are open (the esc menu is one) never mind mods that do so, so the only way to have a consistent GUI is to use your own skin (A "how to maintain your GUI" could be useful for newcomers though).

PS

I can't reproduce the issue using your current release? Are you sure this isn't a mod interaction? (E: Nevermind, something Pilot Assistant was doing fixed it. I'm assuming because I set the GUISkin to the Unity Skin)

EDIT

OnGUI is what the drawQueue's are called in. You can't use GUI methods outside that environment normally.

- - - Updated - - -

You could try setting GUI.Skin back to it's default (http://docs.unity3d.com/ScriptReference/GUI-skin.html : "If you set it null, it reverts to the default Unity Skin"). That won't affect any other mods (because it's the default), and It seems to fix the issue if the interaction with PA is anything to go by

Edited by Crzyrndm
Link to comment
Share on other sites

Is this a computer specific thing now?

To test, I nuked all mods from my steam install, verified cache then copied just this mod back in, issue still happens as per the picture in my last post.

Note that the error only happens when the ESC menu is up, hitting ESC a second time to close the menu and everything reverts back to what I want to see.

Windows 32 bit KSP run through Steam for this test, also happens in my dev environment not run through Steam.

64-bit Windows 7

No errors or related messages that I can find in the log.

What system setup were you not able to replicate this with?

As for the OnGUI thing, I hook directly into the rendering manager so I have more flexibility, so for the purposes of this thread, all the code in question is running "inside OnGUI" I believe.

D.

Edited by Diazo
Link to comment
Share on other sites

That was my bad, my lauch shortcut automatically copies my mods from the development folder, so even though I cleared GameData I had some interference...

Of particular importance in edits

You could try setting GUI.Skin back to it's default (http://docs.unity3d.com/ScriptReference/GUI-skin.html : "If you set it null, it reverts to the default Unity Skin"). That won't affect any other mods (because it's the default), and It seems to fix the issue if the interaction with PA is anything to go by
Link to comment
Share on other sites

Apparently I can't do that.

HighLogic.Skin = null; //does not compile as that is read-only

GUI.Skin = null; //compiles but throws nullref errors all over the place.

At this point if I can figure the scrollbars out I'll be happy. I'll just have to live with the text going funny sometimes.

D.

Link to comment
Share on other sites

Save the default GUISkin when you enter the flight scene and use that then

GUISkin UnitySkin;

// drawCall
if (UnitySkin == null)
UnitySkin = (GUISkin)Monobehaviour.Instantiate(GUI.Skin);

GUI.Skin = UnitySkin;
// continue as normal

Edited by Crzyrndm
Link to comment
Share on other sites

GUI.Window saves the current skin, matrix, etc and restores it when the method ends. The problem you're seeing is that somebody is manipulating those things (GUI.Skin) from a RenderingManager callback but outside of GUI.Window and not restoring them correctly. Your choices are:

  1. Use OnGUI instead of RenderingManager (my preference), or
  2. During startup, clone HighLogic.Skin and make your modifications. Then set the current GUI.Skin inside your DrawWindow methods to the copy you made as the first thing you do inside every DrawWindow callback.

I avoid using RenderingManager because if any other mod using it throws an exception inside their callback, your GUI gets hosed. I'm not sure what flexibility it adds (?)

Link to comment
Share on other sites

Okay, piecing together everyone's comments, I think I've figured out what is going on.

First, there is two GUI Skins, GUI.skin and HighLogic.Skin

GUI.Skin is the Unity Default and SQUAD made there own skin for the HighLogic.skin object. However, they did not clone GUI.skin, they just made a reference copy of it. (As per GUISkin HighLogic.skin = GUI.skin in C# code).

Therefore, when I made a clone of HighLogic.skin, I copied the references present, not the actual values I wanted.

Then for whatever reason, when the ESC menu is opening, the default skin changes, including the font. Because my GUISkin object has a reference to the default font in it, not an explicit font definition, my buttons pick up this font change. (It's Arial normally and Calibri when the ESC menu is open for reference.)

Going back over my GUI with this knowledge, I believe I understand how things are working. I can't get the Arial font to assign yet, but that's just a matter of tracking it down.

@EvilReeper: I use rendering manager because it gives me more flexibility, or thought it did. Based on the Unity docs, you can only use stuff like GUI.Button in it so I went with accessing rendering manager directly.

Looking into it just now because of your post, it appears that was wrong and OnGui allows me to do anything directly accessing the rendering manager does.

http://docs.unity3d.com/ScriptReference/MonoBehaviour.OnGUI.html

So, this is resolved I believe, I just have to wrap the loose ends up.

D.

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...