Basically the title.
I’m creating a GUI, and I wish to use the same base GUI skin, but have separate styles for all the changes etc. But, it seems everything I do to the child, is also affecting it’s parent. I must be doing it wrong, because otherwise, how the damned hell do you all do it?
Cheers.
jedy
September 7, 2011, 12:14pm
2
Well without any code it is hard to guess what exactly is wrong.
But did you note that when you use GUI.skin = whatever; every line of code below it will use the changed skin too. That means instead of changing the skin directly you should cache the old one first. Example:
jedy:
Well without any code it is hard to guess what exactly is wrong.
But did you note that when you use GUI.skin = whatever; every line of code below it will use the changed skin too. That means instead of changing the skin directly you should cache the old one first. Example:
I do this, but when I change anything, it’ll affect the parent style, ALL the way up the list. It’s truly annoying.
jedy
September 7, 2011, 12:21pm
4
How do you change the style?
Directly edit it or just edit the GUI.skin?
Post some example code. Debugging can’t be efficient without the code to debug
using UnityEngine;
using System.Collections;
public class PlayGUI_GUI : MonoBehaviour
{
public GUISkin PlayGUISkin;
private Texture2D tooltipBG;
private string State;
enum ScreenOffset
{
// FrameOffsets: 1 = 0 offset, 2 = full right side, 0 = full left offset
Left = 0,
Centre = 1,
Right = 2,
Top = 0,
Bottom = 2,
};
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
}
void OnGUI()
{
// The screen res
float screenH = Screen.height;
float screenW = Screen.width;
// GUI Skin
GUI.skin = PlayGUISkin;
int fontSize = (int)(15 * (screenW / 1000));
fontSize -= fontSize % 2;
GUI.skin.box.fontSize = (int)(fontSize * 1.5);
GUI.skin.button.fontSize = fontSize;
GUI.skin.label.fontSize = fontSize;
if (true) // Overview
{
// The percentages that the GUI will be "buffered" by
float FbufferH = 0.05f;
float FbufferW = 0.4f;
// The top and left positions for the frame
float frameL = screenW * FbufferW;
float frameT = screenH * FbufferH;
// FrameOffsets: 1 = 0 offset, 2 = full right side, 0 = full left offset
float frameLOffset = (float)ScreenOffset.Right;
float frameTOffset = (float)ScreenOffset.Bottom;
GUI.BeginGroup(new Rect(frameL * frameLOffset, frameT * frameTOffset, screenW - (frameL * 2), screenH - (frameT * 2)));
float groupW = screenW - (frameL * 2);
float groupH = screenH - (frameT * 2);
//float buttonW = (screenW * 0.25f) *0.75f; //100;
//float buttonH = (screenH * 0.125f) *0.75f; //40;
float heightOffset = screenH * 0.25f;
//float buttonSpacing = heightOffset * 0.10f;
// Load the overview frame
GUIStyle overviewStyle = PlayGUISkin.box;
GUI.Box(new Rect(0, 0, groupW, groupH), "Overview", overviewStyle);
GUI.EndGroup();
}
if (true) // Selected object
{
// The percentages that the GUI will be "buffered" by
float FbufferH = 0.45f;
float FbufferW = 0.4f;
// The top and left positions for the frame
float frameL = screenW * FbufferW;
float frameT = screenH * FbufferH;
// FrameOffsets: 1 = 0 offset, 2 = full right side, 0 = full left offset
float frameLOffset = (float)ScreenOffset.Right;
float frameTOffset = (float)ScreenOffset.Top;
GUI.BeginGroup(new Rect(frameL * frameLOffset, frameT * frameTOffset, screenW - (frameL * 2), screenH - (frameT * 2)));
float groupW = screenW - (frameL * 2);
float groupH = screenH - (frameT * 2);
float buttonW = (screenW * 0.25f) *0.75f; //100;
float buttonH = (screenH * 0.125f) *0.75f; //40;
float heightOffset = screenH * 0.25f;
float buttonSpacing = heightOffset * 0.10f;
// Load the Texture for the selected item frame
GUIStyle selectedItemStyle = PlayGUISkin.box;
selectedItemStyle.normal.background = Resources.Load("_art/Materials/GUI/PlayGUI/Textures/SelectedItem/frames/selected-item-frame-centered") as Texture2D;
GUI.Box(new Rect(0, 0, groupW, groupH), "Selected Item", selectedItemStyle);
GUI.EndGroup();
}
if (GUI.tooltip != "")
{
GUI.skin = ScriptableObject.CreateInstance<GUISkin>();
GUI.skin.label.normal.background = tooltipBG;
GUI.skin.label.normal.textColor = Color.white;
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUI.skin.label.font = PlayGUISkin.font;
GUI.skin.button.fontSize = fontSize;
GUI.skin.label.fontSize = fontSize;
float length = GUI.tooltip.Length * 9;
GUI.Label(new Rect(Input.mousePosition.x - length / 2, Screen.height - Input.mousePosition.y + 10, length, 25), GUI.tooltip);
}
}
}
from: // Load the Texture for the selected item frame, till the endgroup
jedy
September 7, 2011, 12:33pm
6
Well everything changes because you edit your your skin every time you want to add custom style.
Try using Unity - Scripting API: GUIStyle .
Or do it your way but do this instead :
The above does not stop it from editing the parent.
var cachedSkin = GUI.skin;
// Load the Texture for the selected item frame
GUIStyle selectedItemStyle = PlayGUISkin.box;
selectedItemStyle.normal.background = Resources.Load("_art/Materials/GUI/PlayGUI/Textures/SelectedItem/frames/selected-item-frame-centered") as Texture2D;
GUI.Box(new Rect(0, 0, groupW, groupH), "Selected Item", selectedItemStyle);
GUI.skin = cachedSkin;
jedy
September 7, 2011, 11:24pm
8
I will check it a bit later.
Anyway note that - Do NOT use Resources.Load in OnGui method. Not even in an update method. It creates a lot of textures which get by the garbage collector, unless you use Resources.UnloadUnusedAssets() .Your editor would probably crash too if you leave your code running for too long.
jedy
September 8, 2011, 7:25am
9
private Texture2D _selected_item_frame_centered;
void OnEnable() {
_selected_item_frame_centered = Resources.Load(“_art/Materials/GUI/PlayGUI/Textures/SelectedItem/frames/selected-item-frame-centered”) as Texture2D;
}
GUIStyle selectedItemStyle = new GUIStyle();
selectedItemStyle.normal = PlayGUISkin.box.normal;
selectedItemStyle.normal.background = _selected_item_frame_centered;
GUI.Box(new Rect(0, 0, groupW, groupH), “Selected Item”, selectedItemStyle);
This should work!
C# classes are assigned as a reference type, that means that when you assign your skin to a temporary variable it becomes a reference to the original variable, respectively editing the referenced variable ( the main skin )
Check this article http://www.yoda.arachsys.com/csharp/parameters.html it should help you understand why this happened.
jedy:
This should work!
C# classes are assigned as a reference type, that means that when you assign your skin to a temporary variable it becomes a reference to the original variable, respectively editing the referenced variable ( the main skin )
Check this article http://www.yoda.arachsys.com/csharp/parameters.html it should help you understand why this happened.
So, basically just like pointers in C++. I was just assigning the parent’s reference etc etc. I thought as such, I suppose that’s one of the quirks of C# I suppose.
Thank you for your assistance and tolerance.
Cheers.
jedy
September 8, 2011, 6:56pm
11
Yeah exactly like the pointers in C++.
Just keep in mind that Class instances act like the pointers in C++ and Struct instances act like variables in C++ ( they aren’t passed by reference ).