Search Unity

Fully Responsive User Interface with Unity GUI

Discussion in 'Assets and Asset Store' started by krides, Aug 12, 2013.

?

Shoud BeginGUI/EndGUI calls go into the class or is it better to leave them alone?

  1. BeginGUI/EndGUI should be called in MakeLabel/ButtonPressed methods of GUISizer

    2 vote(s)
    28.6%
  2. BeginGUI/EndGUI should be called in OnGUI in the user's script

    5 vote(s)
    71.4%
  1. krides

    krides

    Joined:
    Apr 7, 2011
    Posts:
    38
    This is a repost from my blog. Feel free to go there for API reference and additional info.
    http://blog.sergeymohov.com/fully-responsive-user-interface-with-unity-gui/



    The GUISizer class allows you to create fully responsive UIs (completely independent of screen resolution or aspect ratio) using Unity GUI. Hope you will find it useful. If you have any suggestions, shoot.

    GUISizer.cs

    Code (csharp):
    1. /*
    2.  * Script GUISizer by Sergey Mohov (http://sergeymohov.com)
    3.  *
    4.  * Original idea for the resize algorithm by Simon Wittber (http://entitycrisis.blogspot.fr/)
    5.  *
    6.  * Feel free to reproduce this and use for any commercial or non-commercial projects.
    7.  *
    8.  * Although you don't have to, it would be nice of you to mention my name and link to my website
    9.  * if you decide to put this on the Wiki or expand.
    10.  *
    11.  * If you have questions, email me: sergey@sergeymohov.com
    12.  *
    13.  * */
    14.  
    15. using UnityEngine;
    16. using System.Collections;
    17. using System.Collections.Generic;
    18.  
    19. public static class GUISizer
    20. {
    21.         //get the screen resolution once, then adjust the GUI size to that resolution
    22.     public static float WIDTH = 960;
    23.     public static float HEIGHT = 600;
    24.        
    25.         //Get the button sizes
    26.         public const float SMALL_BUTTON_WIDTH = 100f;
    27.         public const float SMALL_BUTTON_HEIGHT = 50f;
    28.         public const float MEDIUM_BUTTON_WIDTH = 200f;
    29.         public const float MEDIUM_BUTTON_HEIGHT = 100f;
    30.         public const float LARGE_BUTTON_WIDTH = 300f;
    31.         public const float LARGE_BUTTON_HEIGHT = 100f;
    32.         public const float BUTTON_GAP = 10f;
    33.        
    34.         private static int fontSizeDefault = 12; //GUI skin's font size should be reset to its default value every time
    35.  
    36.     static List<Matrix4x4> stack = new List<Matrix4x4> ();
    37.        
    38.         //call this funtion in the beginning of OnGUI
    39.     static public void BeginGUI(PositionDef elementsPosition = PositionDef.middle)
    40.         {
    41.         stack.Add (GUI.matrix);
    42.         Matrix4x4 m = new Matrix4x4 ();
    43.         float w = (float)Screen.width;
    44.         float h = (float)Screen.height;
    45.         float aspect = w / h;
    46.         float scale = 1f;
    47.         Vector3 offset = Vector3.zero;
    48.                
    49.         if(aspect < (WIDTH/HEIGHT))
    50.                 {
    51.                         //screen is taller
    52.                         switch(elementsPosition)
    53.                         {
    54.                                 case PositionDef.topLeft:
    55.                         scale = (Screen.width/WIDTH);
    56.                                         break;
    57.                                 case PositionDef.topMiddle:
    58.                         scale = (Screen.width/WIDTH);
    59.                                         break;
    60.                                 case PositionDef.topRight:
    61.                         scale = (Screen.width/WIDTH);
    62.                                         break;
    63.                                 case PositionDef.bottomLeft:
    64.                         scale = (Screen.width/WIDTH);
    65.                         offset.y += (Screen.height - (HEIGHT * scale));
    66.                                         break;
    67.                                 case PositionDef.bottomMiddle:
    68.                         scale = (Screen.width/WIDTH);
    69.                         offset.y += (Screen.height - (HEIGHT * scale));
    70.                                         break;
    71.                                 case PositionDef.bottomRight:
    72.                         scale = (Screen.width/WIDTH);
    73.                         offset.y += (Screen.height - (HEIGHT * scale));
    74.                                         break;
    75.                                 case PositionDef.left:
    76.                         scale = (Screen.width/WIDTH);
    77.                         offset.y += (Screen.height - (HEIGHT * scale)) * 0.5f;
    78.                                         break;
    79.                                 case PositionDef.right:
    80.                         scale = (Screen.width/WIDTH);
    81.                         offset.y += (Screen.height - (HEIGHT * scale)) * 0.5f;
    82.                                         break;
    83.                                 case PositionDef.middle:
    84.                         scale = (Screen.width/WIDTH);
    85.                         offset.y += (Screen.height - (HEIGHT * scale)) * 0.5f;
    86.                                         break;
    87.                                 default:
    88.                                         scale = (Screen.width/WIDTH);
    89.                         offset.y += (Screen.height - (HEIGHT * scale)) * 0.5f;
    90.                                         break;
    91.                         }
    92.                 }
    93.                 else
    94.                 {
    95.                         //screen is wider
    96.                         switch(elementsPosition)
    97.                         {
    98.                                 case PositionDef.topLeft:
    99.                         scale = (Screen.height / HEIGHT);
    100.                                         break;
    101.                                 case PositionDef.topMiddle:
    102.                         scale = (Screen.height / HEIGHT);
    103.                                         offset.x += (Screen.width - (WIDTH * scale)) * 0.5f;
    104.                                         break;
    105.                                 case PositionDef.topRight:
    106.                                         scale = (Screen.height / HEIGHT);
    107.                         offset.x += (Screen.width - (WIDTH * scale));
    108.                                         break;
    109.                                 case PositionDef.bottomLeft:
    110.                         scale = (Screen.height / HEIGHT);
    111.                                         break;
    112.                                 case PositionDef.bottomMiddle:
    113.                         scale = (Screen.height / HEIGHT);
    114.                         offset.x += (Screen.width - (WIDTH * scale)) * 0.5f;
    115.                                         break;
    116.                                 case PositionDef.bottomRight:
    117.                         scale = (Screen.height / HEIGHT);
    118.                         offset.x += (Screen.width - (WIDTH * scale));
    119.                                         break;
    120.                                 case PositionDef.left:
    121.                         scale = (Screen.height / HEIGHT);
    122.                                         break;
    123.                                 case PositionDef.right:
    124.                         scale = (Screen.height / HEIGHT);
    125.                         offset.x += (Screen.width - (WIDTH * scale));
    126.                                         break;
    127.                                 case PositionDef.middle:
    128.                         scale = (Screen.height / HEIGHT);
    129.                         offset.x += (Screen.width - (WIDTH * scale)) * 0.5f;
    130.                                         break;
    131.                                 default:
    132.                             scale = (Screen.height / HEIGHT);
    133.                             offset.x += (Screen.width - (WIDTH * scale)) * 0.5f;
    134.                                         break;
    135.                         }
    136.         }
    137.                
    138.         m.SetTRS(offset, Quaternion.identity, Vector3.one * scale);
    139.         GUI.matrix *= m;
    140.     }
    141.        
    142.         //call this function in the end of OnGUI
    143.     static public void EndGUI()
    144.         {
    145.         GUI.matrix = stack[stack.Count - 1];
    146.         stack.RemoveAt (stack.Count - 1);
    147.     }
    148.        
    149.         //enum that defines position presets
    150.         public enum PositionDef
    151.         {
    152.                 topLeft,
    153.                 topMiddle,
    154.                 topRight,
    155.                 bottomLeft,
    156.                 bottomMiddle,
    157.                 bottomRight,
    158.                 left,
    159.                 right,
    160.                 middle
    161.         }
    162.        
    163.         //enum that defines size presets
    164.         public enum SizeDef
    165.         {
    166.                 small,
    167.                 medium,
    168.                 big
    169.         }
    170.        
    171.         #region methods
    172.         //a method that converts GUIParams into a Rect
    173.         public static Rect MakeRect (GUIParams guiParams)
    174.         {
    175.                 Rect rectangle = new Rect(guiParams.x, guiParams.y, guiParams.width, guiParams.height);
    176.                        
    177.                 return rectangle;
    178.         }
    179.        
    180.         //draws a button and returns true if it was pressed
    181.         public static bool ButtonPressed(GUIParams guiParams)
    182.         {
    183.                 GUI.skin.button.fontSize = (int)guiParams.fontSize;
    184.                 if (GUI.Button(new Rect(guiParams.x, guiParams.y, guiParams.width, guiParams.height), guiParams.text))
    185.                 {
    186.                         GUI.skin.button.fontSize = fontSizeDefault;
    187.                         return true;
    188.                 }
    189.                 else
    190.                 {
    191.                         GUI.skin.button.fontSize = fontSizeDefault;
    192.                         return false;
    193.                 }
    194.         }
    195.        
    196.         //overload method that lets you make custom font sizes
    197.         public static bool ButtonPressed(GUIParams guiParams, int customFontSize)
    198.         {
    199.                 GUI.skin.button.fontSize = customFontSize;
    200.                 if (GUI.Button(new Rect(guiParams.x, guiParams.y, guiParams.width, guiParams.height), guiParams.text))
    201.                 {
    202.                         GUI.skin.button.fontSize = fontSizeDefault;
    203.                         return true;
    204.                 }
    205.                 else
    206.                 {
    207.                         GUI.skin.button.fontSize = fontSizeDefault;
    208.                         return false;
    209.                 }
    210.         }
    211.        
    212.         //draws a label
    213.         public static void MakeLabel(GUIParams guiParams, string additionalText = "")
    214.         {
    215.                 GUI.skin.label.fontSize = (int)guiParams.fontSize;
    216.                 GUI.Label(new Rect(guiParams.x, guiParams.y, guiParams.width, guiParams.height), guiParams.text + additionalText);
    217.                 GUI.skin.label.fontSize = fontSizeDefault;
    218.         }
    219.        
    220.         //overload method that lets you make custom font sizes
    221.         public static void MakeLabel(GUIParams guiParams, int customFontSize, string additionalText = "")
    222.         {
    223.                 GUI.skin.label.fontSize = customFontSize;
    224.                 GUI.Label(new Rect(guiParams.x, guiParams.y, guiParams.width, guiParams.height), guiParams.text + additionalText);
    225.                 GUI.skin.label.fontSize = fontSizeDefault;
    226.         }
    227.        
    228.         #endregion
    229.        
    230.         #region overload methods that let you define a custom style for your GUI element
    231.         //draws a button and returns true if it was pressed
    232.         public static bool ButtonPressed(GUIParams guiParams, GUIStyle style)
    233.         {
    234.                 GUI.skin.button.fontSize = (int)guiParams.fontSize;
    235.                 if (GUI.Button(new Rect(guiParams.x, guiParams.y, guiParams.width, guiParams.height), guiParams.text, style))
    236.                 {
    237.                         GUI.skin.button.fontSize = fontSizeDefault;
    238.                         return true;
    239.                 }
    240.                 else
    241.                 {
    242.                         GUI.skin.button.fontSize = fontSizeDefault;
    243.                         return false;
    244.                 }
    245.         }
    246.        
    247.         //overload method that lets you make custom font sizes
    248.         public static bool ButtonPressed(GUIParams guiParams, int customFontSize, GUIStyle style)
    249.         {
    250.                 GUI.skin.button.fontSize = customFontSize;
    251.                 if (GUI.Button(new Rect(guiParams.x, guiParams.y, guiParams.width, guiParams.height), guiParams.text, style))
    252.                 {
    253.                         GUI.skin.button.fontSize = fontSizeDefault;
    254.                         return true;
    255.                 }
    256.                 else
    257.                 {
    258.                         GUI.skin.button.fontSize = fontSizeDefault;
    259.                         return false;
    260.                 }
    261.         }
    262.        
    263.         //draws a label
    264.         public static void MakeLabel(GUIParams guiParams, GUIStyle style , string additionalText = "")
    265.         {
    266.                 GUI.skin.label.fontSize = (int)guiParams.fontSize;
    267.                 GUI.Label(new Rect(guiParams.x, guiParams.y, guiParams.width, guiParams.height), guiParams.text + additionalText, style);
    268.                 GUI.skin.label.fontSize = fontSizeDefault;
    269.         }
    270.        
    271.         //overload method that lets you make custom font sizes
    272.         public static void MakeLabel(GUIParams guiParams, int customFontSize, GUIStyle style , string additionalText = "")
    273.         {
    274.                 GUI.skin.label.fontSize = customFontSize;
    275.                 GUI.Label(new Rect(guiParams.x, guiParams.y, guiParams.width, guiParams.height), guiParams.text + additionalText, style);
    276.                 GUI.skin.label.fontSize = fontSizeDefault;
    277.         }
    278.         #endregion
    279.        
    280.        
    281.         //struct for GUI elements
    282.         public struct GUIParams
    283.         {
    284.                 //position of the button on screen
    285.                 public float x;
    286.                 public float y;
    287.                
    288.                 //size of the button
    289.                 public float width;
    290.                 public float height;
    291.                
    292.                 /*size of the font of the text written on the button, proportional to the length of the button
    293.                 instead of writing 7 more constructors for custom font sizes, you can override the font in all methods that draw GUI elements*/
    294.                 public float fontSize;
    295.                
    296.                 public string text; //text written in the button
    297.                
    298.                 #region Default style constructors
    299.                 //default everything
    300.                 public GUIParams(string guiText)
    301.                 {
    302.                         text = guiText;
    303.                        
    304.                         //size defaults to medium
    305.                         Vector2 buttonSize = SetSize(SizeDef.medium);
    306.                         width = buttonSize.x;
    307.                         height = buttonSize.y;
    308.                        
    309.                         //position defaults to middle
    310.                         Vector2 buttonPos = SetPosition(PositionDef.middle, width, height);
    311.                         x = buttonPos.x;
    312.                         y = buttonPos.y;
    313.                        
    314.                         fontSize = width/6;
    315.                 }
    316.                
    317.                 //specify all params manually
    318.                 public GUIParams (float posX, float posY, float guiWidth, float guiHeight, string guiText)
    319.                 {      
    320.                         text = guiText;
    321.                        
    322.                         x = posX;
    323.                         y = posY;
    324.                        
    325.                         width = guiWidth;
    326.                         height = guiHeight;
    327.                        
    328.                         fontSize = width/6;
    329.                 }
    330.                
    331.                 //specify position manually, choose size from the list
    332.                 public GUIParams (float posX, float posY, SizeDef size, string guiText)
    333.                 {
    334.                         text = guiText;
    335.                        
    336.                         Vector2 buttonSize = SetSize(size);
    337.                         width = buttonSize.x;
    338.                         height = buttonSize.y;
    339.                        
    340.                         x = posX;
    341.                         y = posY;
    342.                        
    343.                         fontSize = width/6;
    344.                 }
    345.                
    346.                 //specify size manually, choose position from the list
    347.                 public GUIParams (PositionDef position, float guiWidth, float guiHeight, string guiText)
    348.                 {
    349.                         text = guiText;
    350.                        
    351.                         width = guiWidth;
    352.                         height = guiHeight;
    353.                        
    354.                         Vector2 buttonPos = SetPosition(position, width, height);
    355.                         x = buttonPos.x;
    356.                         y = buttonPos.y;
    357.                        
    358.                         fontSize = width/6;
    359.                 }
    360.                
    361.                 //choose size from the list, default position
    362.                 public GUIParams (SizeDef size, string guiText)
    363.                 {
    364.                         text = guiText;
    365.                        
    366.                         Vector2 buttonSize = SetSize(size);
    367.                         width = buttonSize.x;
    368.                         height = buttonSize.y;
    369.                        
    370.                         //position defaults to middle
    371.                         Vector2 buttonPos = SetPosition(PositionDef.middle, width, height);
    372.                         x = buttonPos.x;
    373.                         y = buttonPos.y;
    374.  
    375.                        
    376.                         fontSize = width/6;
    377.                 }
    378.                
    379.                 //choose position from the list, default size
    380.                 public GUIParams (PositionDef position, string guiText)
    381.                 {
    382.                         text = guiText;
    383.                        
    384.                         //size defaults to medium
    385.                         Vector2 buttonSize = SetSize(SizeDef.medium);
    386.                         width = buttonSize.x;
    387.                         height = buttonSize.y;
    388.                        
    389.                         Vector2 buttonPos = SetPosition(position, width, height);
    390.                         x = buttonPos.x;
    391.                         y = buttonPos.y;
    392.                        
    393.                         fontSize = width/6;
    394.                 }
    395.                
    396.                 //choose size and position from the list
    397.                 public GUIParams (PositionDef position, SizeDef size, string guiText)
    398.                 {
    399.                         text = guiText;
    400.                        
    401.                         Vector2 buttonSize = SetSize(size);
    402.                         width = buttonSize.x;
    403.                         height = buttonSize.y;
    404.                        
    405.                         Vector2 buttonPos = SetPosition(position, width, height);
    406.                         x = buttonPos.x;
    407.                         y = buttonPos.y;
    408.                                                
    409.                         fontSize = width/6;
    410.                 }
    411.                 #endregion
    412.         }
    413.        
    414.         //button sizes can be set in this method
    415.         private static Vector2 SetSize(SizeDef size)
    416.         {
    417.                 Vector2 finalSize;
    418.                
    419.                 switch (size)
    420.                 {
    421.                         case SizeDef.small:
    422.                                 finalSize = new Vector2(SMALL_BUTTON_WIDTH, SMALL_BUTTON_HEIGHT);
    423.                                 break;
    424.                        
    425.                         case SizeDef.medium:
    426.                                 finalSize = new Vector2(MEDIUM_BUTTON_WIDTH, MEDIUM_BUTTON_HEIGHT);
    427.                                 break;
    428.                        
    429.                         case SizeDef.big:
    430.                                 finalSize = new Vector2(LARGE_BUTTON_WIDTH, LARGE_BUTTON_HEIGHT);
    431.                                 break;
    432.                         default:
    433.                                 Debug.LogError("Unknown button size, defaults to medium.");
    434.                                 finalSize = new Vector2(MEDIUM_BUTTON_WIDTH, MEDIUM_BUTTON_HEIGHT);
    435.                                 break;
    436.                 }
    437.                
    438.                 return finalSize;
    439.         }
    440.        
    441.         //button positions can be set in this method
    442.         private static Vector2 SetPosition(PositionDef position, float width, float height)
    443.         {
    444.                 Vector2 finalPosition;
    445.                        
    446.                         switch (position)
    447.                         {
    448.                                 case PositionDef.topLeft:
    449.                                         finalPosition = new Vector2(BUTTON_GAP, BUTTON_GAP);
    450.                                         break;
    451.                                
    452.                                 case PositionDef.topMiddle:
    453.                                         finalPosition = new Vector2(WIDTH/2-width/2, BUTTON_GAP);
    454.                                         break;
    455.                                
    456.                                 case PositionDef.topRight:
    457.                                         finalPosition = new Vector2(WIDTH-width-BUTTON_GAP, BUTTON_GAP);
    458.                                         break;
    459.                                
    460.                                 case PositionDef.bottomLeft:
    461.                                         finalPosition = new Vector2(BUTTON_GAP, HEIGHT-height-BUTTON_GAP);
    462.                                         break;
    463.                                
    464.                                 case PositionDef.bottomMiddle:
    465.                                         finalPosition = new Vector2(WIDTH/2-width/2, HEIGHT-height-BUTTON_GAP);
    466.                                         break;
    467.                                
    468.                                 case PositionDef.bottomRight:
    469.                                         finalPosition = new Vector2(WIDTH-width-BUTTON_GAP, HEIGHT-height-BUTTON_GAP);
    470.                                         break;
    471.                                
    472.                                 case PositionDef.left:
    473.                                         finalPosition = new Vector2(BUTTON_GAP, HEIGHT/2-height/2);
    474.                                         break;
    475.                                
    476.                                 case PositionDef.right:
    477.                                         finalPosition = new Vector2(WIDTH-width-BUTTON_GAP, HEIGHT/2-height/2);
    478.                                         break;
    479.                                
    480.                                 case PositionDef.middle:
    481.                                         finalPosition = new Vector2(WIDTH/2-width/2, HEIGHT/2-height/2);
    482.                                         break;
    483.                        
    484.                                 default:
    485.                                         finalPosition = new Vector2(WIDTH/2-width/2, HEIGHT/2-height/2);
    486.                                         Debug.LogError("Undefined position, assigned to middle.");
    487.                                         break;
    488.                         }
    489.  
    490.                 return finalPosition;
    491.         }
    492. }
    493.  
     
    Last edited: Aug 12, 2013
  2. danielng01

    danielng01

    Joined:
    Sep 1, 2013
    Posts:
    2
    Thanks this helped a lot : )
     
  3. Watapax

    Watapax

    Joined:
    Sep 3, 2013
    Posts:
    34
    This is awesome, congrat!!
     
  4. Keizhacook

    Keizhacook

    Joined:
    Oct 9, 2014
    Posts:
    6
    How will i use this? i dont know how, sorry for this question im newbie
     
  5. palakvasoya

    palakvasoya

    Joined:
    Aug 21, 2017
    Posts:
    3
  6. palakvasoya

    palakvasoya

    Joined:
    Aug 21, 2017
    Posts:
    3