Unity IMGUI Scoping

IMGUI (Immediate Mode GUI) is Unitys legacy UI system that handles game UI pre-Unity 4.6 and editor UI. It generally consts of GUI.xyz and GUILayout.xyz calls within an OnGUI function. It could get cumbersome and very difficult to read. Especially if you have a lot of GUI controls.

Whilst I was refactoring Blockout, I came across some APIs that managed to slip passed me when Unity 5.0 was launched. Admittedly, a lot of new APIs can get passed without a programmer knowing as there's usually a large code change in various parts of the engine with each new update. This was GUILayout.xyzScope where xyz was either Horizontal, Vertical, Area or ScrollView. This makes code more readable and easier to understand. A positive side effect is that there is potentially less code that the coder needs to write to accomplish the same thing.

Upon looking into Unity Decompiled on how GUI Scopes functioned, I decided to create my own take on it that auto centred in an axis. This would further eliminate the need to Flexible Spaces every 3 lines. 

HorizontalCenteredScope();

VerticalCenteredScope();

The way these work is similar to how the normal version of both scopes work. At a base level it uses in IDisposable C# interface so it can be wrapped in a using tag. All this means, is that when the class is created it calls the appropriate begining UI functions for GUILayout.BeginXYZ() and GUILayout.FlexibleSpace(). When the disposbale class goes out of scope, usually the end of the using block section, the disposable class gets destroyed so you have to do some cleanup. For this it was the case of calling GUILayout.FlexibleSpace() and GUILayout.EndXYZ() to ensure the encapsulated GUI code is centred. 

This is great advantage of the IDisposbale interface class that GUI.Scope inherits - even though the 'bookend' (begin/end) nature of the GUI code was not what it was originally meant for!

Whilst UI scoping is great, I found out that since I was writing a lot of editor code, it needed to ability to Undo. Blockout usually performs large quantities of changes to multiple objects at the press of a button that all need to be undone together. This is where things get a little more interesting. I  found myself calling the following block of code fairly frequently:

 

 

This was getting cumbersome. In the first released version of Blockout, I call this block of code ~12-15 times. Now the by the book and really 'good' coder in me went OK, lets inherit the IDisposbale class and create an UndoScope() disposable function that encapsulates all of this without the need for much repetition. This however turned out to be a lot of effort for 2am. So to that end, since that class was already written, at least from a base level in the GUI system, I created a derived class which inherited from GUI.Scope.

 

 

A string (the name of the undo operation for that block) is passed on creation of the UndoScope. This increases the current group index and sets the name of that group block. The rest of the code continues as normal for example creating a GameObject. Upon leaving the scope and subsequently the class being destroyed, CloseScope() is called on the class which can perform cleanup and close off any block code that was started in the constructor. 

This has immensely helped in the refactor of Blockout which went from >4000 lines of code to somewhere under <= ~ 2500 - 3000. This has made code navigation 10x easier to locate and read and is something that has now been ingrained into me for whenever I need to write editor code.

Hoorah for the non standard use of the  GUI.Scope class to make a simple disposable class! ( I mean the Microsoft documentation on how to crate a disposable class from an IDisposable interface look super complex for me at 2am which is why I decided to base it off of Unitys GUI.Scope.

Glass Engine 3

Preface

This is the 3 engine I’m building from scratch. The first was a 2D engine built in 2nd year at University and the second was built for my final year computing project. As there are less pressures and time restrictions on this one it should be more fully featured as well as more polished then its predecessors.  I should also point out that this isn’t a how-to guide or tutorial. It is just my observations and whats been occurring as I’m progressing through.

I have actually started a few weeks before and in that time and event based input system was created. A triangle can be rendered to a resizable window. All of the components are black boxed and the renderer is set up to switch between OpenGL 4 and other types (the other types such as DirectX are yet to be created). The project is utilising  C++ 14+ features in Visual Studio 2017.

Note: Due to the planned usage of proprietary middleware, this project is NOT open-source or public. At no point during the production of the engine will the source code be made publicly available.

The planned features include:

  • Swappable graphics renderers (OpenGL4, Vulkan, DirectX 11, DirectX 12, Metal)
  • Multithreaded Rendering
  • NVIDIA PhysX 3.4
  • NVIDIA GameWorks
    • Volumetric Ligting
    • WaveWorks
    • Turf Effects
    • Flow
    • VXAO / HBAO+
    • VXGI (Global Illumination)
    • FaceWorks
  • AMD GPU Open
    • Tress FX
    • AO FX
    • Depth Of Field FX
    • Shadow FX
  • VR Support (OpenVR & Oculus SDK)
  • Cross-platform Editor (Windows and MacOS)
  • Cross-platform build targets (Windows, MacOS & Android)
  • Component based entity sructure
  • Nested Prefabs
  • C# Scripting support
  • GPU Lightmap baking
  • CPU & GPU Particles
  • Audio
    • Spatial Audio (Steam Audio)
    • Dolby Digital / Atmos
    • Reverb Zones
    • Audio Mixer
    • 7.1 Channel Support
  • Post Processing Stack