6 people following this project (follow)

Summary

AffinityUI is a new way to write GUIs for the Unity game engine. Unity's built-in immediate mode GUI system is effective for simple interfaces but quickly becomes unwieldy for complex UI logic. AffinityUI works by providing a declarative, control based API over the top of the existing UnityGUI system, making it possible to easily write both in-game GUIs and editor GUIs with a single, declarative API. Affinity allows you to construct UIs with objects and properties instead of static method calls and return values. You write GUIs by saying what you want built, not how to build it. Affinity does this with virtually no impact on performance.

The project is still in a pre-release stage. A lot more controls need to be added and tested, but most of the work is done. The source is being updated regularly but no binaries are available yet.

Major Features

AffinityUI's major features are its declarative and unified API, fluent interface for constructing GUIs, powerful two-way databinding and update notifications.

Unified API

UnityGUI has four classes for writing GUIs. GUI, GUILayout, EditorGUI or EditorGUILayout are used depending on whether you're writing a GUI for the in-game GUI, editor GUI and whether or not you want automatic layout. Affinity handles the differences for you. Controls lay themselves out automatically based on whichever GUI type you're using.

Databinding

Affinity has a databinding mechanism inspired by WPF. Databinding allows you to specify that the value for a property should be synchronized with another source, without having to worry about updating it by hand. With UnityGUI, you have to manually update the value that goes into each control. Affinity allows you to perform one-way, two-way, or one-way-to-source binding on virtually any property of a control, eliminating tedious and error prone update code.

Update Notifications

Since Affinity uses objects and properties with databinding, it's useful to find out when a certain property has changed due to databinding. Update events makes this easy.

Fluent Interface

User interfaces should be declarative. You should write what you want to be built, not how to build it. Markup languages like XML are declarative and lend themselves well to GUI programming. However, they are overkill for Unity. A simpler solution is to write GUIs entirely in code, but do so in a declarative manner. Affinity uses a fluent interface that lets you write GUI layouts in a manner that looks and feels a lot like a markup language.

Examples

An examples page will be up after more controls are completed, but here's a few snippets for now.

In-Game GUI

A simple in-game example showing only the Affinity methods and not the rest of the script.

// Composite.Create constructs our root composite, it lets us specify
// the target GUI mode (in this case, GUILayout) only once.
//
// Here we've created an Area composite, which is a fixed position layout control.
gui = Composite.Create<GUILayout, Area>()
    .SetDimensions(new Rect(20, 20, 200, 200))
    .Add(new Button("A Button")
            // This will print "A Button was clicked" on each click
            .OnClicked(s => Debug.Log(s.Label + " was clicked"))
            .SetImage(ButtonImage)
        )
    .Add(new Toggle("Checkbox 1")
            // Bind the value of the checkbox to the Option1 variable
            .IsCheckedProperty.BindTwoWay(() => Option1, v => Option1 = v)
            // Binding to the visible property makes this control only visible
            // when Option1 is true, letting us show/hide it using the Toggle control below
            .VisibleProperty.BindOneWay(() => Option1)
        )
    .Add(new Toggle("Checkbox 2")
            // Bind the value of the checkbox to the Option1 variable
            .IsCheckedProperty.BindTwoWay(() => Option1, v => Option1 = v)
            // Print to the console each time the value changes
            .OnToggled((source, old, @new) => Debug.Log(source.Label + " is now " + @new))
        )
    .Add(new Box().SetLabel("sadf"))
    ;

The resulting GUI looks like this:
gamegui_sample1.png

And when one of the toggles is clicked, databinding works to set both of them to false and also hide the first toggle:
gamegui_sample2.png

Last edited Jan 4 2011 at 1:24 AM by olenikm, version 7