Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 straydogstrut · May 03, 2010 at 12:46 AM · texttexture2dguilayout

Correctly position GUILayout controls

For the game we're working on, several NPCs deliver lines of text dialogue. We need to show a graphic with character portraits on either side and space for the dialogue text in the middle.

Since I don't know how big this graphic will be at the moment, i've been looking at using GUILayout for its auto-sizing features. However, it seems the only way to place a GUILayout control involves knowing its size; I need to centre it horizontally on screen and vertically near the bottom of the screen, but I cannot find a straightforward way of doing this. I'd also like to be able to wrap the text since it needs to stay within the middle area of the graphic.

I've been playing around with something like the following but it's not quite right. I've also seen people using FlexibleSpace() but I haven't had much luck there either. I'll be honest, despite all the good things i've read about it, i'm not finding the GUI system very intuitive compared to the way we position guiText/guiTextures. If someone could help me get my head around this i'd be extremely grateful.

var areaWidth : float; var areaHeight : float; var ScreenX : float; var ScreenY : float;

var dialogueBG : Texture2D;

private var showDialogue : boolean = false;

function Start(){ ScreenX = ((Screen.width 0.5) - (areaWidth 0.5)); ScreenY = ((Screen.height) - 200);

}

function OnGUI(){ if (showDialogue) { GUILayout.BeginArea (Rect (ScreenX, ScreenY, areaWidth, areaHeight), dialogueBG);

 GUILayout.Label(myDialogue); 

 GUILayout.EndArea();

}

}

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

3 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Molix · May 03, 2010 at 02:03 AM

I'm trying to picture what you're describing, and it sounds like you've almost got it. It sounds like you can just wrap your label in a horizontal section, surrounded by flexible space; as long as the Label style centers the text (rather than left justifying) you should be all set:

function OnGUI() { GUILayout.BeginArea(Rect (ScreenX, ScreenY, areaWidth, areaHeight), dialogueBG);

GUILayout.BeginHorizontal();

GUILayout.FlexibleSpace();

GUILayout.Label(myDialogue);

GUILayout.FlexibleSpace();

GUILayout.EndHoriztontal();

GUILayout.EndArea(); }

However, if the only reason you're using GUILayout is because of the unknown image size, you could just refer to dialogueBG.width and dialogueBG.height so your code will automatically adjust to whatever the size is.

Comment
Add comment · Show 3 · 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 straydogstrut · May 03, 2010 at 01:06 PM 0
Share

Oh I feel so silly! I realise now that my alignment problems were because the control was always being positioned from the top left. I knew this, but I had been trying to fix it through code, not realising I should set it up correctly in the GUIStyle. I've added a GUISkin and set the Label's alignment to $$anonymous$$iddle Centre. It works, but the text is at the top of the dialogueBG image. Using the Y-offsets moves it down. Also, the text wraps at the edges of the control (ie, it runs over the character portraits on either side). Would I need to nest another area inside the first one to fix this? Thanks

avatar image Molix · May 03, 2010 at 03:15 PM 1
Share

If you make a custom style then you don't even need much of that code, you could just do GUI.Label( rect, myDialogue, customDialogStyle ). To adjust the text inside the dialog, use the GUIStyle.padding, e.g. give it a large value for padding.left and padding.right to account for the face images.

avatar image straydogstrut · May 03, 2010 at 03:21 PM 0
Share

Oh! Or that approach then!

avatar image
0

Answer by straydogstrut · May 03, 2010 at 03:21 PM

So I discovered immediately that GUIAreas cannot be nested. After much head scratching and reading the docs over and over, I realised I could override the width of my label. So now i'm using the following code. Although my previous code was centred after I tweaked the GUISkin, it shuffled over when I specified the width, so Molix's code above is need to pad it out on either side (as far as I understand it).

[EDIT] Re. Molix's last comment, there are other options which i'll put here too.

1) Previous approach using GUILayout and explicitly setting Label's width:

function OnGUI() { GUI.skin = customSkin;

 if (showDialogue) {

     GUILayout.BeginArea(Rect (ScreenX, ScreenY, areaWidth, areaHeight), dialogueBG);  
         GUILayout.BeginHorizontal();
         GUILayout.FlexibleSpace();
         GUILayout.Label(myDialogue, GUILayout.Width(200)); 
         GUILayout.FlexibleSpace();
         GUILayout.EndHorizontal();
     GUILayout.EndArea();

 }

}

2) Same as above but using the padding settings of the GUISkin to define the boundaries for the text (remove GUILayout.Width). Setting a background style in the GUISkin will cause the texture to get squashed, so i'm setting it through code as above.

3) Using GUI.Label with the GUISkin settings used to set the background image and padding amount:

GUI.Label(Rect (ScreenX, ScreenY, areaWidth, areaHeight), myDialogue);

I'm going with option 3 since this will be easier for my artist to tweak the settings himself.

Thanks for the help Molix=)

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 Molix · May 03, 2010 at 05:24 PM 0
Share

No problem! Don't forget to specify the custom style in the GUI.Label call in (3) (unless you're actually changing the default label style).

avatar image straydogstrut · May 03, 2010 at 06:32 PM 0
Share

Yeah, i'm changing the default style for the moment, but i'll add a custom style later when we add more stuff to the GUI. Thank you again.

avatar image
0

Answer by hungrytom · May 25, 2010 at 02:48 PM

Hi,

I just successfully positioned GUILayout.Vertical groups of elements containing variable textual content at absolute coords using the GUILayoutUtility.GetLastRect() method.

The trick was to have my OnGUI() loop just using GUILayout.BeginVertical, ... to lay out my GUI elements on the first frame.

Then use

Rect gui_rect = GUILayoutUtility.GetLastRect();

to get the bounding rectangle of the Vertical group box. This gui_rect can then be stored in an instance variable and used the next time OnGUI gets called to enclose my vertical group in an area using:

if(gui_rect.width>0) GUILayout.BeginArea (
    new Rect(desired_position.x, desired_position.y,
    gui_rect.width,gui_rect.height),areastyle);
    GUILayout.BeginVertical();
    ...
    GUILayout.EndVertical();
if(gui_rect.width>0) GUILayout.EndArea ();

And from now on the GUI elements will be layed out at the desired_position coords with the appropriate dimensions.

...

OK So there is one last thing.. There seems to actually be a bug/feature of GUILayout that means that the GUILayoutUtility.GetLastRect() method returns height=width=1 on the first frame. So I added this correction(/hack) to fix it so the appropriate dims are captured...

if(gui_rect.width>1 && gui_rect.height>1)
    gui_rect = new Vector2(gui_rect.width,gui_rect.height);
else
    gui_rect = new Rect(0,0,0,0);

Here's the complete code for my actual method for better illustration (please note that this code contains some user-defined classes and bits that you don't need to know about - sorry I'm lazy):

private Rect buildOverlay(Overlay o) {
    GUIStyle areastyle = new GUIStyle(style);
    areastyle.normal.background = null;
    if(o.dims[0]>=0 && o.dims[1]>=0) GUILayout.BeginArea (new Rect ((int)o.pos[0],(int)o.pos[1],(int)o.dims[0],(int)o.dims[1]),areastyle);
        GUILayout.BeginVertical();
            // Top
            GUILayout.BeginHorizontal();
                GUILayout.Box("",tl);
                GUILayout.Box("",tp);
                GUILayout.Box("",tr);
            GUILayout.EndHorizontal();
            // Middle
            GUILayout.BeginHorizontal();
                GUILayout.Box("",lt);
                GUILayout.Box(o.txt, style);
                GUILayout.Box("",rt);
            GUILayout.EndHorizontal();
            if(o.close_btn_txt!=null) {
                GUILayout.BeginHorizontal();
                    GUILayout.Box("",lt);
                    GUIStyle button_style = new GUIStyle(style);
                    button_style.alignment = TextAnchor.MiddleRight;
                    if(GUILayout.Button(o.close_btn_txt, button_style)) o.IsDying = true;
                    GUILayout.Box("",rt);
                GUILayout.EndHorizontal();
            }
            // Bottom
            GUILayout.BeginHorizontal();
                GUILayout.Box("",bl);
                GUILayout.Box("",bm);
                GUILayout.Box("",br);
            GUILayout.EndHorizontal();
        GUILayout.EndVertical();
            if(o.dims[0]>=0 && o.dims[1]>=0) {
                GUILayout.EndArea ();
            }
            else {
                Rect gui_rect = GUILayoutUtility.GetLastRect();
                if(gui_rect.width>1 && gui_rect.height>1) o.dims = new Vector2(gui_rect.width,gui_rect.height);
            }
    return new Rect(o.pos[0],o.pos[1],o.dims[0],o.dims[1]);
}

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

No one has followed this question yet.

Related Questions

How to put both text and texture inside a label 1 Answer

Unity 5.2 Text Rendering issue 0 Answers

How can i draw text to a Texture2D? 1 Answer

Bullet Points 1 Answer

Render a typed text to a texture: what is the best way ? 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