Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Some useful classes to help with GUI.

Discussion in 'Immediate Mode GUI (IMGUI)' started by WellFiredDevelopment, Apr 29, 2014.

  1. WellFiredDevelopment

    WellFiredDevelopment

    Joined:
    Jun 16, 2012
    Posts:
    661
    Hello people,

    I've provided a public repository with a couple of useful classes to help with GUI development. Feel free to add to them, extend them or use them in your personal projects.

    BitBucket URL.

    When writing Auto Layout'd gui extensions with Unity, it's always important to remember that almost every action has to have and opposite.

    Example

    Take GUILayout.BeginVertical, for example :

    Code (csharp):
    1.  
    2.     GUILayout.BeginVertical();
    3.     {
    4.         // Do something here
    5.     }
    6.     GUILayout.EndVertical();
    7.  
    This is all well and good, functionality wise, but the user must remember to EndVertical
    Instead, with these Utility class, you can do the following.

    Code (csharp):
    1.  
    2.     using(new GUIBeginVertical())
    3.     {
    4.         // Do something here
    5.     }
    6.  
    Another Example

    When setting the colour on GUI, you've got to remember to cache off the existing colour and re-apply it, not anymore.

    Code (csharp):
    1.  
    2.     var previousColour = GUI.Color;
    3.     GUI.color = Color.red;
    4.     {
    5.         // Do something with red GUI
    6.     }
    7.     GUI.color = previousColour;
    8.  
    becomes

    Code (csharp):
    1.  
    2.     using(new GUIChangeColor(Color.red))
    3.     {
    4.         // Do something with red GUI
    5.     }
    6.  
    With this new approach, the programmer doesn't need to remember to EndVertical, the code takes care of that for them. This isn't exactly revolutionary stuff, and is a commonly used programming idiom, if you'd like to know more, research RAII.

    Regards,
    Terry
     
    Last edited: Apr 29, 2014
  2. Patico

    Patico

    Joined:
    May 21, 2013
    Posts:
    886
    Nice approach, convinient for use, but what about productivity? "Using" keyword creates and disposes object, but OnGUI() method calls very often - up to some times per frame. So, I'm interesting how resonably using of big number of such classes?
     
    Last edited: May 3, 2014
  3. WellFiredDevelopment

    WellFiredDevelopment

    Joined:
    Jun 16, 2012
    Posts:
    661
    The using keyword, wraps that chunk of code up in a try{} finally{} block, so if you're generally steering clear, it would be best to do so here.

    Although OnGUI is executed often for various events I'm never expecting to see any issues in the editor, I probably wouldn't use this code at runtime, since you'd largely want to steer clear of adding any OnGUI methods.

    Though I wouldn't necessarily be so strict as to say never use this idiom at runtime, I have for example used this in the past, in game code to time a section of code. You can take the exact same approach, but in the constructor / dispose method grab the time and do a diff :)

    Code (csharp):
    1.  
    2. using(new Timer())
    3.     PotentiallyExpensiveMethod();
    4.  
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System;
    4. using System.Collections;
    5.  
    6. namespace WellFired
    7. {
    8.     public class Timer : IDisposable
    9.     {
    10.         private float PreviousTime
    11.         {
    12.             get;
    13.             set;
    14.         }
    15.  
    16.         private string TimerName
    17.         {
    18.             get;
    19.             set;
    20.         }
    21.  
    22.         public Timer(string timerName)
    23.         {
    24.             PreviousTime = Time.deltaTime;
    25.             TimerName = timerName;
    26.         }
    27.  
    28.         public void Dispose()
    29.         {
    30.             var timeDiff = Time.deltaTime - PreviousTime;
    31.             Debug.LogError (string.Format("[Timer {0}] took {1}", TimerName, timeDiff));
    32.         }
    33.     }
    34. }
    35.  
    Note: That timer example is something I just nocked together for demonstration purposes, haven't actually tested it.

    Regards,
    Terry
     
    Last edited: May 3, 2014