Download Super UGUI Utilities

Role

Design, Scripting

Project Duration

3 Months, irregular

Technologies Used

  • Unity 6
  • C#
  • GitHub, GitHub Desktop

Additional Attribution

Ninja sprites by pzUH, available on OpenGameArt.Org. Used under the CC0 Public Domain license.

Super UGUI Utilities

The goal of this project was primarily as a simple portfolio piece to begin to demonstrate a little bit of my coding philosophy, as well as just a small portion of the expertise I have developed with Unity's default UGUI user interface system in the course of my professional work. It consists largely of a number of utility components and methods designed to solve common problems faced when using this UI system and establish a pattern for simple, robust, and maintainable development of UI behaviors. A sample scene showing many of these features is included as well and can be viewed directly in your browser below, though much of the uniqueness of the project is only evident in the code.

Some of the key features provided by this set of utilities include:

  • "Behavior" Components

    These utilities establish a pattern for adding behavior to selectable UI elements like buttons and toggles, using components based on common base classes that handle the boilerplate of adding and removing listeners in the OnEnable and OnDisable methods. For example, the base ButtonBehavior script attaches an abstract OnClick method to the click event of a Button element, which is then defined and configured by a concrete subclass, such as a CooldownButton component that makes the button non-interactive for a configurable duration after each click. The intent here is to keep each behavior simple and reusable as much as possible, though the pattern works equally well for bespoke one-off behaviors. Behaviors can then be mixed-and-matched on a single element to create more complex functionality for the user.

  • Super Selectables

    One challenge that can arise sometimes when working with UGUI is that the default "selectable" components (Button, Toggle, Dropdown, etc.) don't publicly expose anything about their selection state. This can make it trickier than expected to apply seemingly simple behaviors, such as changing the colors or sprites of multiple graphics (for example, a button's background, icon, and text) as the element is hovered, pressed, or disabled. One solution would be to use Selectable's ability to activate triggers on an Animator, but this involves a lot of setup and hides the behavior outside of code, which some teams will be more comfortable with than others. It may also be less ideal for certain non-visual behaviors requiring complex logic.

    Super Selectables offer an alternative solution by replacing any given selectable with a derived component (Button becomes SuperButton, Toggle becomes SuperToggle, and so on) that exposes the current state as well as a state change event for other scripts to utilize. This makes it simple to write components that respond to interactions such as hovering or becoming non-interactive in much the same way as Selectable's default color-tinting or sprite swapping logic, including behaviors literally mimicking them for additional graphics. Super selectables inherit from the matching standard selectable type, allowing them to be passed to anything requiring a standard button, toggle, etc. As a convenience, an option has been added to the inspector's context menu for each standard selectable component to automatically upgrade it to the corresponding Super selectable while maintaining all existing properties.

  • Themes

    This project also provides a framework for a powerful theming system, which allows the enforcement of a theme at both edit time and runtime, as well as swapping themes on the fly. This is achieved through a few different pieces, including a theme manager, a theme definition asset consisting of multiple theme styles, and a themed element component that enforces a theme style on another component. It is capable of supporting complex themes involving many different types of elements each with multiple possible styles, but also provides a simplified coding interface that can be used when only one type of element needs to be supported (for example, themes only affecting text styles).

    I chose to design this theming system as a framework that would require some simple scripting for an implementing project to fill in generic types and define which properties of what types of elements a theme is capable of controlling. This makes it appropriate as a starting point for implementing themes tailored to multiple individual projects or different aspects of the same project, without the need to implement core aspects such as theme swapping or style lookup. It does however introduce some additional complexity compared to a bespoke system built from the ground up for the needs of a single project, though this would be a worthwhile tradeoff in many scenarios.