Data Bind for Unity

Update 10.02.2015:

The first version of Data Bind for Unity is available in the Asset Store! Check it out now for a very low initial price and help me with your feedback to further develop it for your needs!

Introduction:

A clean separation between logic/data and visualization is a must-have, not only in software projects (Separation of content and presentation - Wikipedia). This guarantees that the business logic of the application isn’t dependent on the presentation, so the visualization can be easily adapted.

One famous architecture, at least in the Microsoft universe, is the MVVM pattern (Model–view–viewmodel - Wikipedia) which is highly utilized in Windows Presentation Foundation (WPF, Windows Presentation Foundation - Wikipedia). I don’t want to get too much into detail of this framework as it a fully developed business framework with a huge amount of complex stuff.

The part we are interested in is the data binding between the view and the view model. The view model is an additional structure which sits between the view and the logic. It gets its data from the logic of the application and provides an interface for the view to use. Via data bindings the view can use the data provided by the view model to show it to the user.

This is what we adapted with our plugin, so you’ll have a common way how your UI is separated from you game logic to get many cool advantages:

  • Don’t be afraid that UI changes break your game any more, the logic is completely separated
  • Exchange your UI system without touching any logic (e.g. from NGUI to Unity UI)
  • Easily extend the plugin to use it with a custom UI, world objects or custom input commands

Example: Easy Health Bars

Tired of remembering to update two variables (actor.Health = 20.0f, healthLabel.Text = „20“) if the health of your character changed, so the UI is updated correctly?

No problem, Data Bind will take care of this from now on. You just update the data in your context and the UI will update magically!

Okay, not really magically, but without any work on your side. In principal it works like this:

  • The data variables in your context are wrapped in a so called “Data property”
  • The bindings on UI side register for value changes on this properties
  • When your code sets a new value for your data, the property informs its listeners, so they can update the UI properly.

More information

Check out the official documentation with tutorials, examples, API and explanations. If any questions are left, just send me a message or post in this thread!


Original Post:

Hi there,

We are using NData (NData - MVVM framework for NGUI - Community Showcases - Unity Discussions) for a long time now, but unfortunately there seems to be no further development. During the last projects we added many custom extensions to it, fixed some issues and changed some of the core classes a bit.

So the idea came up to build a new data binding/MVVM asset from the ground up which can be used with both NGUI, uGUI and other UI frameworks. The core is practically done. But before we start to write a lot of documentation, tools and tutorials, I’d like to hear your opinion about it and if you have the need for such an asset. Or maybe you even know about an already existing asset that has everything a developer needs to do some nice data binding :slight_smile:

Here are the main features/advantages of the Data Bind asset we would build:

  • Data binding asset for Unity
  • More advanced and more general than NData
  • Separates your view from the logic of your game
  • Exchange your UI system without touching any logic
  • Switch between NGUI and Unity UI
  • Easily extendable for other UI systems (e.g. custom ones)

So, what do you think? Really curious about your opinions!

Guess you guys need a little example to see what I am talking about :slight_smile: I sat down and quickly implemented the most basic architecture to give you a little example.

1. Setup the data context

The first step to work with the data binding module would be to introduce a new context which holds the data that should be shown/manipulated in the view:

public class DataBindTestContext : Context
{
    #region Fields

    /// <summary>
    ///   Data binding property, used to get informed when a data change happened.
    /// </summary>
    private readonly Property<string> textProperty = new Property<string>();

    #endregion

    #region Constructors and Destructors

    public DataBindTestContext()
    {
        this.Text = "Data Bind for Unity";
    }

    #endregion

    #region Public Properties

    public string Text
    {
        get { return this.textProperty.Value; }
        set { this.textProperty.Value = value; }
    }

    #endregion
}

As you can see there’s nothing special about this class, just a storage, using the generic properties of the Data Bind module to capsule the data.

In a real game the data would be filled from your logic system and updated when it changes there. For example in our own logic framework (http://www.slashgames.org/framework/) we use events to tell other systems when some important data changed.

2. Setup your UI

From now on you only work in your scene and can setup how the data your context provides is used. First we have to connect the data context to the UI via a UIContext:

1870680--120202--UIContext.png

For fun I added a little popup which finds all context classes, so it the data context is instantiated when the UIContext awakes. You could also set the data context manually e.g. from another mono behaviour.

3. Use your data

This is all the setup work there is to do. We can now start and use the data properties that we defined in the context. Let’s add a UI label and use the LabelBinding to bind the label text to the Text property from the data context:

1870680--120207--LabelBinding.png

Two steps are necessary for this:

  • First we bind to the property “Text” of the data context with the “Data Binding String” script.
  • Second we add a “Label Binding” which connects the label which should visualize the data and the string data binding.

This automatically updates the text of the label every time the data changes.

---------------------------------------------------------------------------------------------------------------------------------------------

So, what do you think? If some people are interested in such a module I would love to spend some time to further develop it with more UI and data bindings :slight_smile: I’m curious about your feedback!

If you want to try out the example, just download the Unity package (NGUI required): DataBind.unitypackage

1870680–120212–DataBind.unitypackage (22.3 KB)

2 Likes

Love it. This approach has far more advantages than might occur at the first place.

Being able to easily change your UI at any time without having to touch your UI logic essentially means: You can use a label to indicate your current hero health for prototyping, and replace it with a nice health bar later. Without touching any code.

Moreover, you can write fancy binding code once and reuse throughout your game (and even future games). First thing that comes to my mind is showing a timer: You can bind the actual timer value to some float property (e.g. RemainingSeconds), and write a label binding that shows the timer in any format you wish (such as 1:27 or 1m 27s).

2 Likes

I haven’t had a chance to look fully at your framework as I’ve been working through uFrame, Zenject, and MinIOC but I took a quick look at the example above and looks ok.

I understand MVVM (extensive use of NDATA/NGUI) and have my head around IOC/DI but my gut feel is that most of the above solutions - while they are excellent in their own right - are a hammer where a scalpel is needed.

Of course it depends on the app and business needs + tech strategy, but productivity is not just about making the thing so flexible and uncoupled you can’t see the flows anymore.

NDATA took me a little time to get my head around, but it’s lightweight compared to these.

A simple data binding combined with messaging/events (Advanced C# Messenger++ or new Unity events) might be simpler and more modular than some of the more heavyweight solutions mentioned above.
I’ll keep playing with them some more but I really want something lighter.

It’s not that complex to decouple things if you have a binding framework to take care of the front end dependencies and used messaging/events to keep the rest flexible. Sure, it’s not AS flexible as IOC/DI but from what I see you lose even more readability which is also key, especially when picking a project back up after some time.

The biggest issue I see is creating the bindings for custom controls such as customs listview, scroll list or listbox.

Alternatively, how about a publish/subscribe approach instead of data binding?

1 Like

Some UI Publish Subscribe articles

http://lostechies.com/erichexter/2012/11/12/code-review-of-a-publishsubscribe-architecture-using-signalr-in-home-automation-part-4/

Hi @sonicviz ,

We are using the publish/subscribe pattern pretty much for the event manager in our Slash framework. This allows a very clean and strict separation between the different systems inside the logic and it separates the systems from the data contexts.

Between the data contexts and the UI there are just two ways of communication possible:

  1. The UI gets informed if a data value changed if it bound itself to the property.
  2. The data context provides methods which can be called by the UI when a user command occured (e.g. a button was clicked which should fire the weapon => OnFireWeapon). Very often the context does nothing else than queue the correct event, which is handled by the logic.

About the complexity: I’m completely with you. I checked some of the frameworks you mentioned and in my opinion it’s really a bit too much to deal with dependency injection. On the other side, once one understands the basic architecture it might not be that complex anymore. But I haven’t found a use case where I desperately need DI, so I stay away from it right now :wink:

1 Like

Nice. I’ll take a closer look at it.

In my experience (ie: I’ve played a lot of accidental jazz in my time) simple is better on all fronts.

The irony of using a complex system to promote productivity when a simple one will do is not lost on me!
(much as I love patterns, but I’ve grown out of my pattern mania now and just want a clean simple flexible framework)

A framework should always be as simple as possible in my opinion. As a developer I can only use the full potential of a framework if I fully understood how it works. So the simpler the better :slight_smile:

Furthermore I don’t like frameworks which take over all parts of your project. I even restrict Unity to only work on the visualization of our games and work with pure C# in the logic. So I strive for modular plugins which have a clearly defined workspace.

You might want to check out MaterialUI - A Unity UI kit that follows Google's material design guidelines - Community Showcases - Unity Discussions for some nice UI to bind to

1 Like

this also has some data binding
http://mmofoundation.com/

Hi @sonicviz ,

Thanks for the link, it looks like an interesting UI framework! Maybe it’s a good idea to support a big range of UIs to make the data binding asset popular. It’s not much work and really shows the big advantage or such a man-in-the-middle :slight_smile:

Cheers
Christian

Hi @rakkarage ,

Yes, we stumbled upon this framework already, but it bundles too much functionality in one asset in my opinion. Eventually worth a look how they implemented their data binding. Do you know if it is delivered with sources or just the binaries?`

Cheers
Christian

I don’t think you need too many to start, maybe just:

  • uGUI
  • uGUI extended to the Material Framework (see prev link)
  • NGUI

?

Yes, those would be the basic ones, I guess. I could provide a little documentation how to support further UI frameworks, so it could be used for own frameworks as well.

As our asset is released now, please move over to the official thread in the Asset Store forum to ask questions and give feedback: [RELEASED] Data Bind for Unity - Community Showcases - Unity Discussions Thank you! :slight_smile:

Good evening coeing.

I need to add a Setter and configure it by code without using inspector at all. How can I do that?

Hi @Galahad ,

Should be no problem. You can set the Data field of the Setter completely via code. E.g. to link the setter to data from a context, just set the Type to DataBindingType.Context and the Path to the path to the data in the context.

If you tell me which specific setter you have to add, I can give you a small code snippet. But maybe my description already helps :slight_smile:

Thank you for the prompt reply, here te code I’m using:

using UnityEngine;
using System.Collections;
using Slash.Unity.DataBind.UI.Unity.Setters;
using Slash.Unity.DataBind.Core.Presentation;
using UnityEngine.UI;

public class ToggleExample : MonoBehaviour
{
    public ToggleIsOnSetter setter;
    // Use this for initialization
    void Start ()
    {
        setter.Data.Type = DataBindingType.Context;
        setter.Data.Path = "Bool";
        setter.enabled = true;
    }
              
}

The ToggleIsOnSetter on scene has it ‘Path’ set to ‘CUSTOM’ and the ‘Custom Path’ is empty.

The following error issues:

Console

InvalidCastException: Value is not a convertible object: ToggleStateContext to System.Boolean
System.Convert.ToType (System.Object value, System.Type conversionType, IFormatProvider provider, Boolean try_target_to_type) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Convert.cs:2941)
System.Convert.ChangeType (System.Object value, System.Type conversionType) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Convert.cs:2490)
Slash.Unity.DataBind.Core.Presentation.DataBinding.GetValue[Boolean] () (at Assets/Slash.Unity.DataBind/Scripts/Core/Presentation/DataBinding.cs:131)
Slash.Unity.DataBind.Foundation.Setters.SingleSetter1[System.Boolean].OnObjectValueChanged (System.Object newValue) (at Assets/Slash.Unity.DataBind/Scripts/Foundation/Setters/SingleSetter.cs:90) Slash.Unity.DataBind.Foundation.Setters.ComponentSingleSetter2[UnityEngine.UI.Toggle,System.Boolean].OnObjectValueChanged (System.Object newValue) (at Assets/Slash.Unity.DataBind/Scripts/Foundation/Setters/ComponentSingleSetter.cs:46)
Slash.Unity.DataBind.Foundation.Setters.SingleSetter.OnEnable () (at Assets/Slash.Unity.DataBind/Scripts/Foundation/Setters/SingleSetter.cs:65)
UnityEngine.Behaviour:set_enabled(Boolean)
ToggleExample:Start() (at Assets/Slash.Unity.DataBind/Examples/ToogleBool/ToggleExample.cs:15)

Regards =]

Hi @Galahad ,

Just tried your example, thanks a lot for providing it!

It looks like the DataBinding is initialized too early for your adjustments to have an effect. The SingleSetter base class initializes its binding in Awake already. This happens before you do your adjustments in the Start method of the ToggleExample script.

What you can do (and what I might change after some testing in the asset) is to do the initialization of the binding in the Start method, so it is only done when the script is enabled.

Just copy the Awake method of the SingleSetter class (Foundation/Setters/SingleSetter.cs, line 36), rename it to Start() and remove the AddBinding call from the Awake method. This worked for me. It shouldn’t create any bigger problems, but if you get one let me know!

Cheers
Christian

It worked wonders!

I congratulate you for this great product.

Many thanks
Thiago