📜 ⬆️ ⬇️

We use MVVM in Unity3D using NData



Hello! In this post I would like to tell you, my favorite Habr, about the plugin, which increased my productivity in working with UI several times. The link with which I work is as follows: Unity3D + NGUI + NData . Optionally, you can use IoC + DI, but the ideal option to work under iOS, Android and WinPhone, until it was found.

You can read about the pattern here or here . One of the spikes is data binding, i.e. linking the view with the data and automatically notifying that the data of the desired view is changed.
')
Information about the NData plugin can be found on the website . And yes, it costs $ 45)

(in the picture above one of the last games that I collected using Unity3d + NGUI + NData)

As it was

Previously, to make a user interface, you had to create one / several classes (GUIManager, MenuView, GameViewetc.), Which contained references to the components of visual elements (UILabel, UISprite, UIGrid, etc.). Then it was necessary to update this component in some place. I had a change in presentation in the same classes. But similar actions began to appear, such as:
- depending on the variable of type bool show / hide element
-update if string variable has changed
-if some condition is met, for example, Points> 5, then show / hide an element

Those. I had to write the same type of code all the time. They even began to think how to simplify it. And here…

Meet NData

My friend once told me about NData. And when he demonstrated filling and managing the list of items in the grid using two components and one property, I was amazed. Here it is, the speed of development!

I will quote the list of features with of. site:
- Two-way text bindings (including multi-bindings) with native .NET formatting capabilities.
- Two-way float bindings for sliders.
It is also possible to make sure that it is free.
- Command bindings for your buttons.
It is a list of items for your code.
- Code snippets for Visual Studio and Mono Develop.
- Editor script for bindings validation.

As you can see, almost any application can be built on this list of binders. What I, actually, am doing lately.

Not everything is so smooth in reality. After importing the plugin, errors are corrected and need to be corrected. I recorded the vidos how to install the plugin, how to work with components, etc.

What is binding? This is the usual MonoBehaviour script that binds this UI element to some variable in the code via reflection. A variable is created of a special generic type (for example, Property), which adds the ability to notify you when a variable is changed.


(text binding in variable with text in UILabel)


(binding event of pressing the button to the method)

Grid example:
1. Create a collection of views (+ the view itself) that we want to cram into the grid / table
private readonly EZData.Collection<ProductItemContext> _privateItems = new EZData.Collection<ProductItemContext>(false); public EZData.Collection<ProductItemContext> Items { get { return _privateItems; } } 


2. We bind it to the table / grid through binding and assign a prefab to which we will bind a view of the table element:


3. Somewhere in the code we are working with a collection (Add, Remove, Clear, GetItem (n)) and all changes will be displayed on the screen.
 ... Items.Add(new ProductItemContext(prod)); ... 


Ready code can be inserted from templates / snippets

Pechalka

It would be all very nice if it did not affect the speed of the application. The same VisibilityBinding makes a passage through the entire object hierarchy and turns off the UIWidget. Those. GetComponents () all the time, which is sad.
 ... private void SetVisible(Transform tr, bool visible) { foreach(var collider in tr.GetComponents<Collider>()) { collider.enabled = visible; } foreach(var widget in tr.GetComponents<UIWidget>()) { widget.enabled = visible; } } ... 


This is the way to check the text changes.
 void Update(){ if(_characterName != NewCharacterName){ _characterName = NewCharacterName; } } 

The source code is different, but the principle is the same.

All my “hacks” for optimization ended up with the inheritance of the NguiBaseBinding class from CachedMonoBehaviour, in which transform and gameObject are cached. There is an idea how to optimize the constants GetComponent: make a flag for bindings, indicating that the element is static and its components can be cached + make its own implementation of GetComponent, which would take a component from the cache by the flag. But it looks like a crutch for a crutch)

In general, in a situation where you need to frequently change the visibility, it is easier to move an element to some outrageous coordinates, it will be much faster (for example, if we turn off the window with many elements, then simply transfer it to x: 10000 y: 10000 z: 0 and no need to go through the whole hierarchy and look for components).

Total

Now collecting UI has become much more fun and easier. The list of bindings covers almost all requests. If suddenly something is not there, then you can easily add your binding, and this is done very simply. I use both for toys and for business applications.

Of course, this is not a “golden bullet”, but the universality of this solution is striking. I use it along with Uniject (IoC + DI, which doesn’t work under WinPhone), so I forgot about NullReferenceException long ago (no need to worry about creating / destroying objects, setting references to objects) and you can easily replace model / services / views.

Habrahabrovtsy, share, please, your experience developing interfaces!

Thanks for attention!

PS After the release of the game faced with many cries that it is a game of perverts / for perverts / the name of the worst in the world / uporoty bear, etc. We did not think that everyone would associate the name exclusively with the notorious Pedobir) Do they have something in common except consonance? Change the name)

Source: https://habr.com/ru/post/240875/


All Articles