Sofortige GUI - ja oder nein? [geschlossen]


38

Ich habe vor einigen Jahren an der Anwendungsentwicklung mit vielen "beibehaltenen" GUI-Systemen gearbeitet (siehe unten), wie MFC, QT, Forms, SWING und verschiedenen Web-GUI-Frameworks. Ich fand die Konzepte der meisten GUI-Systeme immer zu kompliziert und umständlich. Die Anzahl der Rückrufereignisse, Listener, Datenkopien und die Anzahl der Zeichenfolgen - Konvertierungen (und so weiter) verursachten im Vergleich zu anderen Teilen der Anwendung immer Fehler und Kopfschmerzen. (Auch bei "ordnungsgemäßer" Verwendung von Datenbindungen / Modellen).

Jetzt schreibe ich Computerspiele :). Bisher habe ich mit einer GUI gearbeitet: Miyagi (nicht bekannt, aber im Grunde die gleiche Idee wie alle anderen Systeme.)

Es war schrecklich.

In Echtzeit-Rendering-Umgebungen wie Games habe ich das Gefühl, dass "beibehaltene" GUI-Systeme noch veralteter sind. Benutzeroberflächen müssen in der Regel nicht automatisch gestaltet werden oder die Größe der Fenster muss während des Betriebs geändert werden. Stattdessen müssen sie sehr effizient mit sich ständig ändernden Daten interagieren (wie 3D-Positionen von Modellen in der Welt).

Vor ein paar Jahren bin ich auf "IMGUI" gestoßen, das im Grunde wie ein Sofortgrafikmodus ist, aber für Benutzeroberflächen. Ich habe nicht zu viel Aufmerksamkeit geschenkt, da ich mich noch in der Anwendungsentwicklung befand und die IMGUI-Szene selbst weder wirklich breit noch erfolgreich wirkte. Trotzdem scheint die Herangehensweise so sexy und elegant zu sein, dass ich auf diese Weise etwas für das nächste Projekt schreiben wollte (ich konnte niemanden bei der Arbeit überzeugen: (...)

Lassen Sie mich zusammenfassen, was ich unter "beibehalten" und "unmittelbar" verstehe:

Beibehaltene GUI: In einer separaten Initialisierungsphase erstellen Sie "GUI-Steuerelemente" wie Beschriftungen, Schaltflächen, Textfelder usw. und verwenden eine beschreibende (oder programmatische) Methode, um sie auf dem Bildschirm zu platzieren - alles bevor etwas gerendert wird. Steuerelemente behalten den größten Teil ihres eigenen Status im Speicher, z. B. X-, Y-Position, Größe, Rahmen, untergeordnete Steuerelemente, Beschriftungstext, Bilder usw. Sie können Rückrufe und Listener hinzufügen, um über Ereignisse informiert zu werden und Daten im GUI-Steuerelement zu aktualisieren.

Sofortige GUI: Die GUI - Bibliothek besteht aus One-Shot "RenderButton", "render", "RenderTextBox" ... Funktionen (edit: Sie erhalten durch die nicht zu verwechseln RenderPräfix. Diese Funktionen führen auch die Logik hinter den Steuerelementen aus, z. B. das Abfragen von Benutzereingaben, das Einfügen von Zeichen, die Geschwindigkeit der Zeichenwiederholung, wenn der Benutzer eine Taste gedrückt hält usw.), die Sie aufrufen können, um ein Steuerelement "sofort" zu rendern (doesn ' Es muss nicht sofort auf die GPU geschrieben werden (normalerweise wird es für den aktuellen Frame gespeichert und später in entsprechende Stapel sortiert). Die Bibliothek hält für diese keinen "Zustand". Wenn Sie eine Schaltfläche ausblenden möchten, rufen Sie einfach nicht die RenderButton-Funktion auf. Alle RenderXXX-Funktionen mit Benutzerinteraktion wie Schaltflächen oder Kontrollkästchen haben Rückgabewerte, die angeben, ob z. B. der Benutzer auf die Schaltfläche geklickt hat. Also dein "RenderGUI" Die Funktion sieht aus wie eine große if / else-Funktion, bei der Sie Ihre RenderXXX-Funktionen aufrufen oder nicht, abhängig von Ihrem Spielstatus, und die gesamte Datenaktualisierungslogik (wenn eine Taste gedrückt wird) ist in den Ablauf eingebunden. Der gesamte Datenspeicher befindet sich "außerhalb" der Benutzeroberfläche und wird bei Bedarf an die Renderfunktionen übergeben. (Natürlich würden Sie die großen Funktionen in mehrere Funktionen aufteilen oder einige Klassenabstraktionen verwenden, um Teile der GUI zu gruppieren. Wir schreiben keinen Code mehr wie 1980, oder?;))

Jetzt stellte ich fest, dass Unity3D für seine integrierten GUI-Systeme den gleichen grundlegenden Ansatz verwendet. Gibt es wahrscheinlich auch ein paar GUIs mit diesem Ansatz?

Dennoch ... scheint es beim Umsehen eine starke Neigung zu beibehaltenen GUI-Systemen zu geben? Zumindest habe ich diesen Ansatz nur in Unity3D gefunden und die ursprüngliche IMGUI-Community scheint eher ... leise zu sein.

Hat also jemand mit beiden Ideen gearbeitet und eine starke Meinung?

Bearbeiten: Ich bin am meisten an Meinungen interessiert, die aus der Praxis stammen. Ich denke, es gibt im IMGUI-Forum viele heftige Diskussionen über jede "theoretische Schwäche" des unmittelbaren GUI-Ansatzes, aber ich finde es immer aufschlussreicher, über Schwächen der realen Welt Bescheid zu wissen .



Danke für den Link. Ich nehme an, Sie beziehen sich auf den Kommentar von Kylotan . Interessant ..;)
Imi

1
Hah, ich habe gerade eine Antwort geschrieben, als ich bemerkte, dass meine Meinung bereits gesehen wurde ... trotzdem werde ich sie trotzdem posten.
Kylotan,

2
Es ist eine Schande, dass diese Fragen geschlossen werden! Das sind die Meinungen, nach denen ich suche, wenn ich die gleiche Frage habe.
Harald Scheirich

Antworten:


34

Nein. Ich habe bezahlte Spieleev-Arbeiten an einer schrecklichen GUI mit beibehaltenem Modus und an einer schrecklichen GUI mit sofortigem Modus durchgeführt, und obwohl beide mich dazu gebracht haben, mir die Augen aus den Augen zu lassen, ist der Ansatz mit beibehaltenem Modus immer noch eindeutig der bessere.

Die Nachteile des Sofortmodus sind vielfältig:

  • Sie machen es Künstlern und Designern nicht leicht, das Layout zu konfigurieren.
  • Sie bringen Sie dazu, Logik mit Präsentation zu mischen.
  • Sie erschweren es, ein einheitliches Eingabemodell zu haben.
  • Sie entmutigen komplexe Steuerelemente für dynamische Daten (z. B. Listenansichten).
  • Ebenen werden sehr umständlich (z. B. wenn ich RenderComboBox aufrufe, kann das Dropdown-Feld möglicherweise noch nicht gerendert werden, da es über den Rest des Fensters hinausgehen muss - dasselbe gilt für QuickInfos) l
  • Die Konfiguration des Rendering-Stils erfolgt mit globalen (ick) oder zusätzlichen Funktionsargumenten (ick).
  • Die Leistung kann schlecht sein, da das Aufrufen all dieser Funktionen zum Abfragen von Werten, die sich möglicherweise geändert haben oder nicht, dazu neigt, viele kleine Objekte zu erstellen, was den Speichermanager belastet.
  • ... und ich kann mir gar nicht vorstellen, wie schmerzhaft es wäre, jemandem zu erlauben, Teile der Benutzeroberfläche herumzuziehen und sie neu zu ordnen. Sie müssten eine Datenstruktur pflegen, die Ihnen sagt, wo Sie alles rendern sollen - ähnlich wie Sie ein System mit beibehaltenem Modus selbst umschreiben.

GUIs im Sofortmodus sind verlockend für alleinerziehende Programmierer, die ein schnelles HUD-System wünschen, und für diesen Zweck sind sie großartig. Für alles andere ... sag einfach nein.


1
@ImmanuelScholz: Hast du gedacht, dass vielleicht beibehaltene GUIs nicht wirklich "so hässlich" sind?
Nicol Bolas

1
GUI-Bibliotheken sind in der Regel nicht relevant, da sie verschiedene Probleme behandeln - Eingabe, Rendern und Datenzugriff - und jede davon wird stark vom Rest des Programms beeinflusst. Dies bedeutet, dass Benutzer Abstraktionsebenen hinzufügen, um die GUI für verschiedene Programme, Eingabegeräte und Renderer wiederverwendbar zu machen, und dies auf Kosten einer komplexeren Verwendung.
Kylotan,

2
Hinzu kommt, dass es keinen Konsens darüber gibt, wie GUIs im beibehaltenen Modus (MVC, MVP und MVVM sind 3 gängige Ansätze) erstellt oder wie sie angeordnet werden (aus Daten? Aus Code?) Oder wie das Eingabeverhalten angehängt wird ( Inline-Skripte wie im Web (Benannte Signale / Slots - In-Place-Ergebnisse wie bei IMGUIs) und diese fehlende Standardisierung haben die Entwicklung von One True Way für GUIs behindert.
Kylotan

2
Für die Konfiguration des Layouts durch einen Künstler ist ein Editor erforderlich, unabhängig davon, ob Sie eine beibehaltene oder eine sofortige GUI verwenden. Dieser Punkt ist völlig ungültig. Das Mischen von Logik und Präsentation ist DER Grund, warum Sie die grafische Benutzeroberfläche im Sofortmodus verwenden. Dies ist kein Fehler, sondern das, was Sie möchten, im Gegensatz zu dem Durcheinander, bei dem mehr grafische Benutzeroberfläche erhalten bleibt. Sie verstehen nicht einmal so viel. Für die Konfiguration sind keine globalen oder zusätzlichen Argumente erforderlich, wenn die API gut konzipiert ist. Jeder Nachteil, den Sie erwähnen, ist in einer sauberen Sache lösbar. Am wichtigsten ist jedoch, dass Sie eine Benutzeroberfläche für ein Spiel schreiben, nicht für Photoshop.
Dreta

3
@dreta: Mein Punkt über artist config ist, dass es Dinge gibt, die sich über einen Editor nur sehr schwer ändern lassen, ohne dass Sie Ihre eigene Ebene für beibehaltene Modi darüber schreiben (z. B. was zu tun ist, wenn eine Schaltfläche angeklickt oder neu angeordnet wird) Elemente). IMGUI eignet sich gut für sehr einfache und triviale Visualisierungen, sonst nichts.
Kylotan

31

Als jemand mit fünf oder sechs Jahren Erfahrung mit IMGUI auf dem Desktop fühle ich mich verpflichtet, es zu verteidigen. Alle Antworten (und die Frage selbst) basieren auf einer sehr eingeschränkten Definition von IMGUI, und es scheint eine Menge fragwürdiger Behauptungen zu geben.

Ein Großteil davon stammt aus der Annahme, dass eine IMGUI-Bibliothek keine Daten im Verborgenen speichern kann. Das stimmt überhaupt nicht. Eine ausgefeilte IMGUI-Bibliothek speichert in der Tat ungefähr so ​​viele Daten wie eine entsprechende RMGUI-Bibliothek. Der Unterschied besteht darin, dass eine IMGUI-Bibliothek die Ergebnisse meist zwischenspeichert , während eine RMGUI-Bibliothek den autoritativen Status beibehält. In der IMGUI stellt die Anwendung eine Funktion bereit, die den aktuellen Modellstatus annimmt und eine GUI für diesen Status erstellt. Dies ist die maßgebliche Definition der GUI. Die Bibliothek ist dafür verantwortlich, dass die Bildschirm-GUI mit dem Ergebnis dieser Funktion übereinstimmt. Dies bedeutet nicht, dass diese Funktion für jeden Frame vollständig ausgewertet und die GUI vollständig neu erstellt werden muss. Darum geht es beim Caching.

Mit dieser Ansicht von IMGUI können Sie tatsächlich ein erweitertes Layout erstellen, und die Leistung ist recht vernünftig. Sie können auch den aktuellen autorisierenden Status beibehalten, wenn dies die Benutzeroberfläche vereinfacht. Der Sinn von IMGUI ist nicht, dass die Anwendung alles beibehält. Die Anwendung möchte wahrscheinlich nicht die Position jeder Bildlaufleiste und den erweiterten / reduzierten Zustand jedes Baumknotens speichern müssen. Der Punkt ist, in der Lage zu sein, den Inhalt dieser Baumknoten und ihre Existenz prozedural zu spezifizieren.

Ich würde alle IMGUI-Kritiken Punkt für Punkt durchgehen und beantworten, aber ich verstehe nicht wirklich viele von ihnen. Die meisten davon scheinen aus einer fundamentalen Überzeugung zu stammen, dass IMGUI hackisch und RMGUI gut strukturiert ist, was meiner Meinung nach auf die oben genannten Missverständnisse zurückzuführen ist. Es gibt keinen inhärenten Grund, warum IMGUI-Bibliotheken Probleme mit der Komplexität haben sollten oder mit globalen Elementen übersät sein oder Logik mit Präsentation mischen müssen. Ich werde sagen, dass die Vorteile von IMGUI weniger wichtig werden, je künstlerischer Ihre Inhalte sind, aber ich bin mir nicht sicher, warum dies bei künstlerischen Inhalten tatsächlich schlimmer wäre. (Ich persönlich verwende keine künstlerischen Inhalte, abgesehen von Stylesheets für Dinge wie Farben, Schriftarten / Rahmengrößen usw., aber ich verstehe nicht, warum es schwieriger zu implementieren ist als für RMGUI.)

Meiner Meinung nach ist IMGUI zweifellos eine gute Sache. Es gibt Ihnen ein viel besseres Modell für die Überlegung über Ihre GUI. Es wird viel funktionaler und reaktiver, und Sie minimieren die Menge an veränderlichem Zustand, über den Sie nachdenken müssen. Andererseits ist die Implementierung einer hoch entwickelten IMGUI-Bibliothek eine ziemliche Herausforderung und definitiv schwieriger als die Implementierung einer entsprechenden RMGUI-Bibliothek. Es ist ein Kompromiss zwischen Bibliothekskomplexität und Anwendungskomplexität. Wenn Sie komplexe Apps (oder sogar viele einfache Apps) erstellen möchten, ist der Kompromiss sehr gut. Wenn Sie dies für eine einzige App tun und es ist ziemlich einfach, werden Sie Ihr Ziel wahrscheinlich mit RMGUI schneller erreichen.

Auf jeden Fall viel Glück!


5
"Es gibt keinen inhärenten Grund, warum IMGUI-Bibliotheken Probleme mit der Komplexität haben sollten oder mit Globals übersät sein oder Logik mit Präsentation mischen müssen." Es ist sehr schwer zu erkennen, wie die üblichen IMGUI-Schaltflächen aufgerufen werden, z. "Wenn Button (x, y) dann Aktion" kann nicht Mischlogik mit Präsentation genannt werden. Wenn Sie keine Rendering-Details an den Aufruf übergeben, können Sie ihn nicht positionieren oder formatieren (außer bei einem globalen oder statischen), und wenn Sie die Schaltflächenlogik nicht sofort verarbeiten, ist dies nicht wirklich eine grafische Benutzeroberfläche im Sofortmodus. Könnten Sie ein Beispiel zur Erklärung geben?
Kylotan

4
Der OpenGL-Kontext ist aufgrund des Umfangs des gemeinsam genutzten Status eine große Fehlerquelle, und selbst mit dieser API wurde im Laufe der Jahre der Wechsel in den Beibehaltungsmodus vollzogen, da der Sofortmodus weder die erforderliche Flexibilität noch die erforderliche Leistung bot.
Kylotan

1
Es ist nicht die Nebenläufigkeit, die das Problem ist, sondern ein großer Block von Zuständen, der gemeinsam genutzt wird. Die GUIs im beibehaltenen Modus kapseln den relevanten Status mit dem Steuerelement, für das sie gelten, und eine solche Kapselung wird normalerweise aus Gründen als gut angesehen, die hier nicht wiederholt werden müssen. Meine spezifischen Bedenken sind in meiner Antwort oben aufgeführt, und ich habe noch keinen IMGUI-Ansatz gesehen, der nicht unter allen von ihnen leidet.
Kylotan

3
Qualifiziert sich ein CSS-Stylesheet auch als "ein großer gemeinsam genutzter Statusblock"? Auf jeden Fall weiß ich nicht, was Ihre besondere Erfahrung mit IMGUI ist, aber wenn Sie an IMGUI-Ansätzen interessiert sind, die nicht unter diesen Problemen leiden, empfehle ich Ihnen, meine Antwort oben zu lesen und die zu lesen IMGUI-Forum zu Molly Rocket. Es ist wahr, dass es keine perfekte IMGUI-Bibliothek von der Stange gibt, die Sie herunterladen und in wenigen Minuten verwenden können. Wenn Sie jedoch daran interessiert sind, eine zu erstellen, stehen Informationen zur Verfügung und Menschen, die bereit sind, zu helfen.
Tom

1
CSS-Stylesheets sind statische Zustände. ziemlich verschieden von OpenGL-Kontexten, die extrem dynamisch sind!
Kylotan

12

Die GUI-Bibliothek besteht aus den einmaligen Funktionen "RenderButton", "RenderLabel", "RenderTextBox" ..., die Sie aufrufen können, um ein Steuerelement "sofort" zu rendern (muss nicht sofort in die GPU geschrieben werden. Normalerweise wird es gespeichert für den aktuellen Frame und später in entsprechende Chargen sortiert).

Ich würde sogar sagen, dass dies keine GUI-Bibliothek darstellt. Es ist nur eine Reihe von Rendering-Funktionen.

Das Rendern der GUI ist der einfachste Teil beim Erstellen einer GUI. Nehmen Sie zum Beispiel ein Textfeld. Ich gehe von einem möglichst einfachen Fall aus: einem einfachen einzeiligen Eingabetextfeld.

RenderTextBoxwird nur ein Textfeld zeichnen. Es führt eine einfache Textmessung durch und zeichnet die Glyphen auf dem Bildschirm. Es wird nicht

  • Stellen Sie fest, dass der Benutzer mit der Maus im Steuerelement geklickt hat, und bewegen Sie den Cursor an die richtige Stelle in der Zeichenfolge.
  • Stellen Sie fest, dass der Benutzer die Maus im Steuerelement doppelt angeklickt hat, und wählen Sie einen Textblock aus.
  • Stellen Sie fest, dass der Benutzer die Taste "Home" gedrückt hat, und bewegen Sie den Cursor an die Vorderseite des Texts.
  • Stellen Sie fest, dass der Benutzer eine gültige Taste gedrückt hat, und ändern Sie die Zeichenfolge entsprechend. Wenn Text ausgewählt wurde, wird der ausgewählte Teil durch den eingefügten Text ersetzt.

Ich kann weitermachen, aber ich denke, mein Standpunkt ist klar. Wenn Sie RenderTextBoxein Textfeld zeichnen möchten , erhalten Sie lediglich ein statisches, nicht funktionsfähiges Textfeld. Jede tatsächliche Funktionalität muss von Ihnen implementiert werden.

Text messen und Glyphen zeichnen? Das ist der einfache Teil der GUI-Arbeit. GUI steht für "Graphical User Interface". Die letzten beiden Wörter, in denen Sie Eingaben vom Benutzer entgegennehmen und etwas damit anfangen, sind der schwierige Teil.

Die Spieler erwarten, dass die GUI-Steuerung vernünftig funktioniert. In einer Umgebung im PC-Stil (dh Maus und Tastatur) erwarten die Spieler, dass ein Textfeld wie ein normales Textfeld funktioniert, wenn es angezeigt wird. Sie erwarten, dass sie sich mit den Pfeiltasten darin bewegen, nach vorne springen und mit home enden und löschen, Buchstaben darin auswählen usw.

Das bedeutet, dass Sie den gesamten UI-Code implementieren müssen. Sie müssen testen, auf welches Steuerelement geklickt wurde. Sie müssen dann etwas basierend darauf tun, auf welches Steuerelement geklickt wurde. Sie müssen das Konzept eines "aktiven" Steuerelements haben, das Tastatureingaben erhält. Verschiedene Steuerelemente müssen auf verschiedene Arten der Benutzerinteraktion unterschiedlich reagieren.

Grundsätzlich wirst du eine TextBoxWindowKlasse brauchen .

Angenommen, Sie implementieren einen Bildschirm mit Spieloptionen. Sie haben also verschiedene Gruppen von Optionen: Gameplay, Grafik, Sound, Steuerung usw. Sie haben also eine Liste verschiedener Gruppen auf der linken Seite des Bildschirms. Jede Gruppe zeigt eine Reihe von Steuerelementen an, die der Benutzer bearbeiten kann. Was passiert, wenn der Benutzer die Tabulatortaste drückt?

Nun, es hängt davon ab, welche Steuerung aktiv ist. Wenn eines der Gruppensteuerelemente aktiv ist (das zuletzt angeklickt wurde), wird es in die nächste Gruppe verschoben. Wenn stattdessen eines der Steuerelemente in der Gruppe aktiv ist, wird zum nächsten Steuerelement in dieser Gruppe gewechselt. So soll das System funktionieren.

Ein aktives Steuerelement muss also nicht nur Tastatureingaben verarbeiten, sondern auch alle unverarbeiteten Eingaben für das Steuerelement, dessen Eigentümer es ist , bereitstellen . Entweder das, oder die Steuerelemente müssen sich in einer Art verknüpfter Liste befinden, damit sie hin und her gehen können. Das bedeutet, dass in jedem Steuerelement ein Standardverhalten vorhanden sein muss.

Das klingt immer mehr nach einer beibehaltenen GUI, nicht wahr? Der einzige Unterschied ist, dass ... Sie die harte Arbeit erledigen. Die Verwendung einer anderen Benutzeroberfläche soll dazu beitragen , weniger Arbeit zu erledigen. Der Aufwand, der erforderlich ist, um eine Benutzeroberfläche so zu gestalten, wie es der Benutzer erwartet, ist jedoch nicht trivial.

Denken Sie daran: Die Benutzeroberfläche ist nicht für Sie, sondern für Ihre Benutzer . Es ist für den Spieler. Es sollte sich so verhalten, wie sie es erwarten. Und wenn nicht, dann haben Sie versagt.

Benutzeroberflächen müssen in der Regel nicht automatisch gestaltet werden oder die Größe der Fenster muss während des Betriebs geändert werden.

Das ist ein begrenzter und einschränkender Gedanke.

Ich konnte das spiel über verschiedene Spiele mit unterschiedlichen UI Bedürfnisse geben, dass einige Spiele tun müssen resizeable Fenster und so weiter. Aber es gibt ein viel größeres Problem.

Ihre Art des Denkens führt zum Problem der unbegründeten Weltraumschlachten.

Wenn Sie dieses Spiel noch nie gespielt haben, ist es ein billiges, Indie- und sehr GUI-lastiges Spiel. Das eigentliche Gameplay wird in der GUI erledigt (es ist eine Art "Einheiten aufstellen und ihnen beim Kampf zusehen"). Das Problem?

DIE GUI KANN NICHT UMGESTELLT WERDEN!

Oh, das ist in Ordnung, wenn Sie einen normalen Monitor verwenden oder normales Sehvermögen haben. Aber wenn Sie zum Beispiel ich sind, der einen lächerlich großen Monitor ausführt (einer, der so groß ist, dass Windows die Größe des gesamten Texts vergrößert, damit Sie ihn tatsächlich lesen können), ist dies schrecklich . Der Text ist mikroskopisch. Es gibt keine Möglichkeit, die Schriftgröße zu ändern.

Zugegeben, GSB ist ein GUI-basiertes Spiel, daher ist es für sie absolut unentschuldbar. Ein GUI-Lite-Spiel kann wahrscheinlich damit durchkommen.

Gehen Sie niemals davon aus, dass Ihr Benutzer sein Spiel genau so betrachtet, wie Sie es sind. Das ist Torheit.

Ein GUI-System, das sich selbst auf die Auflösung des Benutzers skalieren lässt, eine wirklich auflösungsunabhängige GUI, erfordert, dass das Layout Teil des GUI-Systems selbst ist. Wenn Sie das nicht bereitstellen, wird Ihr Text auf dem riesigen Monitor einer anderen Person winzig klein erscheinen. Das ist keine gute Sache.

Ich würde also sagen, dass Ihr Denken zu diesem Thema kurzsichtig ist. Sie haben das Zeug brauchen. Sie benötigen die beibehaltenen GUIs. Oh, Sie brauchen möglicherweise nicht alles, was ein bestimmtes GUI-System bietet. Aber du brauchst etwas davon.

Die Boilerplate-Arbeit, die Sie ausführen müssen, um Daten an das System zu senden, ist ein geringer Preis, der zu zahlen ist, und bietet eine angemessene Sicherheit, dass der Benutzer mit den Steuerelementen richtig interagieren kann und die Größe an die Bedürfnisse des Players angepasst wird.

Möglicherweise können Sie eine grafische Benutzeroberfläche im Sofortmodus verwenden, wenn Sie nicht viele Benutzereingaben vom Player abrufen. Aber das wäre schon alles.


5
Verstehen Sie das bitte nicht falsch, aber ich darf Sie noch einmal fragen, ob Sie aus der Praxis mit der tatsächlichen Verwendung eines unmittelbaren GUI-Ansatzes in einer Spieleentwicklung sprechen (und wie ich Ihrer Meinung nach die Hälfte der Entwicklung wahrscheinlich ersetzen) vor frust;))? Übrigens: Ihre abgebildete Funktionalität einer Textbox kann (und wird z. B. in UnityGui.TextField) in der RenderTextBox-Klasse implementiert. Außerdem verbietet nichts in der unmittelbaren GUI-Methode dem Bibliotheksdesigner, Klassen für GUI-Steuerelemente zu verwenden, falls dies angemessen ist. Allein die Verwendung wäre grundsätzlich anders.
Imi

1
@Immanuel: "Übrigens: Ihre abgebildete Funktionalität einer Textbox kann (und ist zB in UnityGui.TextField) in der RenderTextBox-Klasse implementiert werden." Sie sagten, das RenderTextBoxsei eine Funktion , keine Klasse. Ihre Unterteilung in "Sofortmodus" und "Beibehaltener Modus" scheint also in dem Bereich zu liegen, in dem die Daten gespeichert sind, und nicht in dem Bereich, in dem sie verwaltet werden. In diesem Fall müssen Sie diese Unterscheidung in Ihrer Frage klarer machen, da dies darauf hindeutet, dass eine grafische Benutzeroberfläche im Sofortmodus einfach Inhalte auf den Bildschirm zeichnet. Dass es keine Eingabe bekommen kann (weil das einen dauerhaften Zustand erfordern würde) und so. Also was ist es?
Nicol Bolas

1
@ImmanuelScholz: "Ich sehe kein Argument gegen einen allgemeinen" Sofort-GUI-Ansatz "in diesem" Ich dachte, ich habe es ziemlich gut erklärt: Jemand muss den Code schreiben . Jemand muss Eingaben machen, den Cursor bewegen, ein aktuelles Steuerelement verwalten, das Layout bearbeiten usw. Die Beschreibung einer grafischen Benutzeroberfläche im Sofortmodus verliert all dies , und all dies ist wichtig für alles, was die einfachste Ausgabe ausmacht GUI. Ich verstehe Ihr Argument also nicht, dass der "unmittelbare GUI-Ansatz" irgendwelche Nachteile hat.
Nicol Bolas

1
Entschuldigung, das war mein Fehler. msgstr "... implementiert in der RenderTextBox - Funktion" (nicht Klasse). Es ist eine Funktion, die Benutzereingaben verarbeitet, und die Bibliothek enthält einen bestimmten Status (wie z. B. die aktuelle fokussierte Steuerung). Bitte keine Straftat beabsichtigt, aber kann ich davon ausgehen, dass Sie nur "unmittelbare GUI" von meinem Beitrag hier kennen und weder in IMGUI noch in Unity3D gui geschaut haben? Ich habe hier sicherlich nicht nachvollziehbar beschrieben, was eine "unmittelbare GUI" im Detail enthält, ich wollte es nur zusammenfassen, damit es nicht um ganz andere Dinge geht (zB um nicht mit dem "unmittelbaren Grafikmodus" verwechselt zu werden).
Imi

2
@ImmanuelScholz: "Ich habe sicherlich nicht nachvollziehbar beschrieben, was eine" unmittelbare GUI "hier im Detail enthält" Dann ist deine Frage unvollständig. In der Tat ist es eher irreführend, weil "Sofortmodus" einen Mangel an Staat impliziert. Der Begriff "erhalten" ergibt sich aus der Tatsache, dass es Zustand hat. Wenn also eine grafische Benutzeroberfläche im Sofortmodus den Status beibehält, ist dies kein Sofortmodus.
Nicol Bolas

8

Vor einiger Zeit IMGUIs auch mein Interesse geweckt, als einen Test ich ein paar Tutorials schrieb mich mit den Techniken vertraut zu machen (Start hier , wenn Sie daran interessiert ist , aber es ist nicht viel mehr als C # / XNA + die ursprüngliche ‚Tutorial‘ hier ) .

Ich mochte IMGUIs für eine kurze Zeit sehr, da die angezeigten Informationen immer aktuell und korrekt sind (da es keinen Status gibt, den Sie immer für aktuelle Daten verwenden). Aber am Ende habe ich das Interesse verloren, so dass ich jetzt normalerweise wieder beibehaltene GUIs verwende.

Am Ende dachte ich, dass die Unmittelbarkeit der GUI es schwieriger machte, die GUI von den Daten zu trennen, und manchmal versuchte ich, die Dinge durch die Einführung eines Status stärker zu entkoppeln, wodurch die Eleganz der IMGUIs gebrochen wurde. Ich denke auch nicht, dass das Schreiben von Code für beibehaltene GUIs mehr Arbeit ist als das Schreiben von Code für IMGUIs, und ich mag es, dass beibehaltene GUIs ausgelöst und vergessen werden können, und ich mag Ereignisse wirklich :).

Jedes Mal, wenn jemand erwähnt, dass IMGUIs etwas in mir sind, möchte er es erneut versuchen und sich mehr Mühe geben, um es richtig zu machen, da es wirklich etwas Eleganz gibt. Ich bin mir jedoch nicht hundertprozentig sicher, ob es Ihnen immer die Arbeit erleichtern wird. Ich würde sagen, probieren Sie es aus, versuchen Sie es vielleicht so, wie ich es getan habe, und schreiben Sie einige Tutorials (ich finde, der beste Weg, neue Techniken zu lernen, besteht darin, sie anderen zu erklären).


8

Ich habe viel mit dem Unity3D-GUI-System gearbeitet, das so funktioniert, wie Sie es beschrieben haben. Und ich muss sagen, ich hasse es aus Leidenschaft.

"Sofort" -Ansatz funktioniert in einigen Fällen wirklich gut. Erstens, wenn Sie nur ein paar Tasten und Beschriftungen benötigen - denken Sie beispielsweise an Shooter-HUD. Sie mit "beibehaltenem" Ansatz zu erstellen ist nicht sehr schwierig, aber mit UnityGUI sehr einfach. Der zweite Fall ist, wenn Sie viele Steuerelemente auf dem Bildschirm platzieren müssen, sich aber nicht wirklich für das Layout interessieren. Vor allem, wenn exakte Steuerungen nur zur Laufzeit bekannt sind. Dies ist in keinem Spiel wirklich nützlich, aber sehr hilfreich, wenn Sie Tools erstellen, die im Unity-Editor ausgeführt werden.

Jede halbkomplexe Benutzeroberfläche, zum Beispiel für ein (MMO) -RPG oder ein Strategiespiel, wird jedoch unweigerlich zu einem fürchterlichen Durcheinander von nicht entzifferbarem Code, der voller Sonderfälle und unzähligen Möglichkeiten ist. Wenn Sie eine solche GUI erstellen, haben Sie normalerweise ein ziemlich spezifisches Layout, das für jede Auflösung geeignet sein muss und in der Lage sein muss, alle von Ihnen gesendeten Daten anzuzeigen. Sie müssen beispielsweise einige Schaltflächen nach unten bewegen, um Platz für längeren Text zu schaffen. Mit der "beibehaltenen" GUI können Sie ein Steuerelement haben, das dies automatisch erledigt. Im "Sofort" -Modus gibt es keine Steuerelemente, sodass Sie alles explizit ausführen müssen.

Ein weiteres Problem mit UnityGUI (nicht sicher, ob es sich um alle GUIs im Sofortmodus handelt) besteht darin, dass beispielsweise ein Button()Anruf ohne Berücksichtigung anderer GUI-Aufrufe ausgeführt werden kann. Wenn sich also eine Taste über einer anderen befindet, werden durch Klicken beide Tasten gleichzeitig gedrückt. Dies ist definitiv nicht das, was der Benutzer erwartet.

Um mit all dem leben zu können, habe ich immer meinen eigenen Wrapper um UnityGUI geschrieben, der es in ein System mit "beibehaltenem" Modus verwandelt: Steuerelemente, die ihren eigenen Status speichern und einfach die erforderlichen GUIFunktionen für jeden Frame für mich aufrufen .

Ich kann nicht sagen, dass der Modus "sofort" definitiv schlechter ist als "beibehalten", aber ich fühle mich auf jeden Fall viel besser, wenn ich im Modus "beibehalten" arbeite.


1
Ja, ich habe jedes dieser Probleme mit der Unity-GUI erlebt und hasse es daher. Es ist großartig für schnelle statische HUDs, aber ein echtes Problem für alles andere.
Kylotan,

6

Ich werde IMGUI hier verteidigen, da einige der zuvor aufgeführten Probleme gelöst werden können, wenn Sie bereit sind, den Code dafür zu schreiben. Wenn Sie den Code dafür schreiben, verfügen Sie außerdem über eine robuste Bibliothek, die wiederverwendbar ist und nur sehr selten geändert werden muss.

  • Laden der GUI aus dem Schema

Vielleicht scheint es auf den ersten Blick so, als hätten Künstler mit IMGUI nicht viel Flexibilität. Dies wird durch das Laden des GUI-Layouts aus einem XML- oder JSON-Schema gelöst oder verbessert.

  • Menüebene Anrufe zeichnen

Dieses Problem wird durch Sortieren gelöst. Sie sollten eine UI-Manager-Klasse erstellen, die die Zeichenreihenfolge sortiert. Ich habe dieses Problem in C # XNA mit verschiebbaren, klickbaren Fenstern gelöst, die übereinander zeichnen. Ich kann Pseudocode posten, wenn ich gefragt werde.

  • Listenfelder

Können Sie Zeichenfolgen aus einem Array zeichnen? Können Sie Rechteckbereiche anhand der Höhe und Breite der Schriftarten dieser Zeichenfolgen definieren? Können Sie ein Verhältnis der Größe Ihrer Bildlaufschaltfläche zur Höhe aller zusammengefügten Rechtecke erstellen? Dann sind Sie auf halbem Weg zum Erstellen eines Listenfelds mit einer scrollbaren Schaltfläche, um nach oben oder unten zu gelangen. Ich dachte, es würde schwierig werden, aber es stellte sich als viel einfacher heraus, als ich dachte. Keine Puffer, keine Zustände, keine Rückrufe.

  • Trennen von Daten von der GUI

Lassen Sie nicht zu, dass die einzelnen Bedienfelder, Schaltflächen und Felder die Daten enthalten. Ich weiß, dass mein erster Versuch von IMGUI sofort war, aber nur im grafischen Sinne. Ich habe den Fehler gemacht, Daten auf der Benutzeroberfläche zu speichern. Es war fast eine philosophische Veränderung, anders darüber nachzudenken, wo Daten über die Benutzeroberfläche platziert und geändert werden sollen.

  • GUI von SDKs

Dies ist die Grenze und Funktionalität des SDK-Codes, nicht Ihres. Ich finde, dass die SDK-Benutzeroberfläche (Hammer, Unity, UDK) ohnehin eine neue Sprache ist. Tatsächlich ähneln sie mir als Windows.Forms. Beide sind auf die größtmögliche Wahrscheinlichkeit ausgelegt und haben daher ein zusätzliches Gewicht in der Komplexität.

und schau dir das an> http://mollyrocket.com/861


4

Benutzeroberflächen müssen in der Regel nicht automatisch gestaltet werden oder die Größe der Fenster muss während des Betriebs geändert werden. Stattdessen müssen sie sehr effizient mit sich ständig ändernden Daten interagieren (wie 3D-Positionen von Modellen in der Welt).

Das hängt vom jeweiligen Genre und Spiel ab. Ein gutes Lagerverwaltungssystem ist für die meisten Rollenspiele von entscheidender Bedeutung. Sie möchten etwas, das Layouts für Sie handhabt, Bildlaufleisten, Drag & Drop, QuickInfos und andere Funktionen unterstützt, die mithilfe der beibehaltenen GUI viel einfacher zu implementieren sind.

Ich kann mir keine Möglichkeit zum Ziehen und Ablegen mit einer sofortigen Benutzeroberfläche vorstellen, die nicht viel Jonglieren oder Speichern des Benutzerstatus erfordert, z Bit.

Aus gestalterischer Sicht stelle ich mir eine Welt ohne meine GUI-Ereignisse nur schwer vor. Außerdem ist eine Sofort-GUI nicht mit OOP kompatibel, wodurch Sie gezwungen sind, auf die prozedurale Programmierung zurückzugreifen.

Die Einfachheit, die unmittelbare GUIs bieten, geht mit zusätzlicher Komplexität in Ihrem Code einher, die mit zunehmender Komplexität der von Ihnen benötigten Benutzeroberfläche rapide zunimmt. Wobei eine gut erhaltene GUI ursprünglich komplexer ist, aber besser skaliert. Unter einem gewissen Grad an Komplexität ist eine sofortige GUI ausreichend, aber für die meisten Situationen würde ich eher eine beibehaltene GUI bevorzugen.


1
Ich möchte Sie fragen: Kommt Ihre Meinung aus der Praxis oder aus theoretischen Überlegungen, wenn Sie beide Systeme betrachten? Ähm .. das klingt härter als beabsichtigt, sorry .. Was ich meine ist: Ich teile Ihre Meinung und Bewertung von einem theoretischen Aspekt. IMGUI-ähnliche Systeme führen höchstwahrscheinlich zu weniger OOPish-Code (wenn das ein Problem ist), sie haben Probleme mit Steuerelementen, die einen bestimmten Status erfordern usw. Es ist einfach ... normale GUI-Systeme sind auch schon für sich genommen sehr groß und komplex, so dass Sie eine Menge Komplexität hinzufügen müssen, bis Sie sich diesen Systemen überhaupt nähern.
Imi

1
Immanuel, Sie müssen keine realen Entwicklungserfahrungen haben, um zu wissen, dass viele Spiele Auto-Layout und anpassbare Fenster benötigen.
Kylotan

1
@Immanuel Scholz Ich gebe zu, dass ich viel mehr Erfahrung mit beibehaltenen Benutzeroberflächen habe. ein OSS-Projekt zu unterhalten und mit ihnen zusammengearbeitet zu haben, obwohl meine Karriere (die zugegebenermaßen noch sehr jung ist). Ich habe jedoch das UI-System von Unity3D verwendet und es dupliziert, als ich zu XNA gewechselt bin. Meine beibehaltene Benutzeroberfläche wurde entwickelt, weil ich es leid war, denselben Hack von Projekt zu Projekt zu kopieren, um eine einheitliche Funktionalität zu erreichen.
ClassicThunder

@Kylotan durch "Größenänderung von Fenstern" Ich meine, dass Sie die Größe von UI-Elementen durch Ziehen (oder auf andere Weise) und durch automatisches Layout ändern können. Wenn Sie die Größe ändern, passt sich die UI auf eine "nette" Weise an, wie wenn Sie Bildlaufleisten anzeigen und mehrere zuweisen Linien für Schaltflächenleisten und so weiter. Ja, manchmal sehe ich das in Spielen, aber es ist in Desktop-Anwendungen viel häufiger. Außerdem denke ich, dass gute UIs mit veränderbarer Größe auch für beibehaltene GUI-Systeme nicht die einfachste Sache sind.
Imi

1
Größenveränderbare Fenster und Autolayout sind fast dasselbe. In GUIs im Retained-Mode kennt jedes Steuerelement seine Größe (ob es sich bei der Ausführung ändert oder nicht) und das automatische Layout ist im Grunde eine rekursive Größenüberprüfung. Wahrscheinlich ist es in Spielen wichtiger als in Desktop-Apps, da wir Vollbild-GUIs in verschiedenen Seitenverhältnissen und auf verschiedenen Plattformen erwarten.
Kylotan
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.