Jump to content
Unity Insider Forum

DataBinding in uGUI


Mark

Recommended Posts

Hi,

 

laut Doku gibt es keine wirkliche Möglichkeit Daten an UI Elemente zu binden. Wie genau betreibt ihr euer Databinding?

 

Ich suche eine elegante Art dies zu vollbringen so dass ich am besten nur das Binding erstelle und der Rest wird von einem generellen System übernommen.

 

Für die die grade etwas verwirrt sind was genau DataBinding ist:

 

Ohne Databinding:

void TakeDamage(int damage)
{
 Health -= damage;
 healthDisplay.Text = Health.ToString();
}

 

Mit DataBinding (stark pseudocode):

Bind(Health, healthDisplay);
...
void TakeDamage(int damage)
{
 Health -= damage; //healthDisplay.Text wird automatisch geupdatet.
}

 

Passend zum Binding, wie löst man am besten folgende Situation:

 

Ich habe eine Liste die sich verändern kann, gefüllt mit Elementen. Ich möchte diese Liste nun darstellen, jedes Element soll dabei eine Art Prefab verwenden (1 Prefab für alle Elemente der Liste) um damit in der UI etwas darzustellen. Als beispiel wäre dies ein Inventar und jedes Item soll dabei durch eine Reihe von Labels, ein Icon und ein paar Buttons repräsentiert werden.

 

Dies ist kein konkretes Beispiel, aber wie würde man das mit uGUI machen? Alles programmatisch per Code aufbauen, so wie ich vermute, oder gibts da was moderneres?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also ich bin mir nicht sicher was du genau machen willst, aber ich habe bislang es noch nicht anders gesehen ausser das du

healthDisplay.Text = Health.ToString();

 

schreibst zum updaten. Kannst natürlich alle UIs zum Updaten vll in einer anwendung zusammen packen. In dieser checkst du immer auch nochmal durch ne

if(healthDisplay.Text == Health.ToString()) (wobei ich mit nicht sicher bin ob das geht) und rufst dann zb die void UpdateUi() auf um alle UI elemente die in diesem Programm angebunden sind upzudaten. Ka ob das vll Performanter ist.

Und dann

void TakeDamage(int damage)

{

Health -= damage;

UpdateUi();

}

 

Oder eben deiner erste variante was vll mehr sinn machen würde wenn nur 1 UI Elemente sich auch verändert.

 

Ka obs dir was brachte^^ Ich habs aber bis jetzt noch nicht anders gesehen

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich weiß was du meinst. Und ja, es ist nicht so ohne.

Bei deinem Textbeispiel sende ich z.B. immer den Inhalt einer Variable zum text.Text und zwar jedes Frame.

Meine Void beschreibt nur die Variable neu.

Also habe ich ein Script, welches ständig an die GUI Elemente sendet.

Bei so einem Inventar würde ich so ähnlich arbeiten. Ich hätte vorgefertigte GUI Elemente, die außerhalb des Screens liegen und immer dann eingeblendet würden (also im Screen positioniert) wenn gewisse Bedingungen eintreten. Sind die Bedingungen nicht mehr, werden die Elemente ins off gesetzt.

Jeder Inventargegenstand wäre ein Prefab welches an entsprechende Position gesetzt würde. (Sowas löse ich über Buttons die ihre Info über mehrere Arrays bekommen. Der Arrayplatz ist gleichzeitig der Slotplatz)

Diese Infoelemente der Inventargegenstände bekommen auch von einem Sendescript ständig, oder je nach event, die Infos übergeben.

 

Also hat jedes GUI Element (welches sich ändert) eine Variable zugewiesen, die über ein Sendescript abgefragt wird und dem Element als Wert oder was auch immer übergeben wird.

Link zu diesem Kommentar
Auf anderen Seiten teilen

ich arbeite im geschäft selber nur mit DataBinding. Und in VisualStudio und WinForms is das eine mega angenehme sache! Bin auch schon in Unity dran da was gescheites zu finden aber leider noch ohne wirklichen Erfolg. Deshalb wenn du das was hast dann bitte bitte mit mir, oder besser mit uns hier teilen!

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich hab mir das jetzt nicht en Detail angesehen, aber es gibt schon mindestens ein DataBinding-Paket für Unity UI auf dem Asset Store (Data Bind for Unity) und einige für NGUI. Bei dem verlinkten Beispiel wird das MVVM Pattern eingesetzt. An sich dürfte es nicht so schwer sein, eine Abstraktion zu schreiben, die z.B. eine "Text"-Komponente mit einem Property verknüpft, wobei man entweder das Property von außen beobachten und auf Veränderungen reagieren muss ("saubere" Implementierung, aber umständlich zur Laufzeit), oder die Implementierungen der Properties an die Abstraktion anpassen muss (da würde dann beim Setter einfach geprüft, ob der Wert sich tatsächlich ändern, und wenn ja ein entsprechender Event gefeuert, der dafür sorgt, dass die text-Eigenschaft von Text geupdated wird, ggf. mit entsprechenden Formatierungsanweisungen).

 

In die andere Richtung, als z.B. bei InputField müsste diese Abstraktion halt dafür sorgen, dass auf onEndEdit oder onValueChange ein Listener registriert wird, der die Daten ins Modell zurückschreibt. Wahrscheinlich ist das sogar der einfachere Teil (zumindest wenn man es sauber abstrahieren möchte).

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ok sorry jetzt muss ich doch mal nachhaken, was damit überhaupt gemeint ist,

meint ihr damit dass wenn sich der wert x verändert sich dann auch automatisch der hp balken ändern muss??

dafür wird doch dann extra der scrollbalken benutzt ohne slider oder nicht? dann ist es doch gebinded, wenn ich es richtig in erinnerung habe.

Link zu diesem Kommentar
Auf anderen Seiten teilen

DataBinding & MVVM ist im grunde nichts anders wie. Du hast deine View also deine UI und dein ViewModel. (Die logik).

 

Angenommen du hast Rollenspiel und dort ein Label in welchem die Namen der Charaktere drinn stehen sollen, welchen du gerade den fokus gibst.

 

Also Label (UI) hat also eine Text Property, welche immer den Namen der Charaktere anzeigt.

 

Ohne Databinding würdest du immer sagen

 

if(Hans == Fokus)

Label.Text = Hans;

if(Frodo == Fokus)

Label.Text =Frodo;

 

Wenn du jetzt aber einen neuen Character erzeugst, der Dieter heißt, dann musst du erst wieder folgendes in deinem Script ändern nämlich:

 

if(Dieter == Fokus)

Label.Text =Dieter;

 

usw.

Das ist extrem nervend und einfach nicht wirklich schön. Klar bei kleineren sachen is das kein Thema aber jetzt hab mal 1000 Characters dann machst du 1000 Zeilen code einfach mal nur um dein Label anzupassen^^

Extrem eklig!

 

Bei Databinding sagst du einfach nur

 

Die Namen deiner Charaktere werden an dein Label gebindet.

 

Du sagst also im Script nur einmal

 

Label.Text = Fokus.Character.Name

 

 

Das ist jetzt wirklich sehr einfach ausgedrückt aber hab versucht es so verständlich wie möglich zu erklären.

 

Ein anderes bsp. ist du hast eine Lebensanzeige.

 

Jetzt sagt du immer wenn du schaden bekommst soll dein Leben.Text zur runtime geupdated werden.

 

Also Leben.Text = CurrentHealt;

 

Du hast eine CurrentHealth Property und der sagst du dann im grunde nichts anderes wie, wenn dein Wert sich ändert(du also schaden bekommst) habe den neuen wert.

 

Durch das DataBinding musst du also nur einmal sagen:

 

Leben.Text = CurrentHealt;

 

Jetzt wird immer wenn du schaden bekommst dein currentHealth geupdate und somit auch dein Leben.Text.

 

Weiß jetzt nicht wie das mit dem ScrollBalken ist, da ich den noch nie genutzt habe, wenn du aber sagst das er sich automatisch anpasst je nachdem was du für einen x Wert übergibst dann sollte dieser Balken auch gebunden sein.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi, danke für die Antworten.

 

Das Asset was hier gezeigt wurde sieht schon ganz gut aus. Ich brauchte (ich selbst nur) aber etwas AssetStore unabhängiges wie ich gemerkt habe.

 

Daher bin ich drauf und dran das Rad neu zu erfinden. Man lernt auch was dabei, ich zumindest. DataBinding zB ist ein echt feines Thema.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 4 weeks later...

Hmm also MVVM mal dahin gestellt ich kenn das von Angular und ja das ist geil.

 

Aber bei Unity ist was "ähnliches" bereits drinne oder etwa nicht? Wenn UI und Data Grundlegend am selben GameObject (später prefab) kleben, kann ich über den aktuellen Scope (in UnityScript "this") immer das eigene Objekt verwalten. Das heisst wenn ich das Objekt als "Dieter" im Data spawne, weiss die GUI vom eigenen Objekt her (denn da liegt auch data) das im Label "Dieter" stehen muss. Selbes gilt für jedes andere Objekt ebenfalls....oder etwas nicht?

 

(würde gern weiter ausholen, aber muss mal eben weg xD)

 

MfG

 

Nax

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...