GUI immediata - yae o no? [chiuso]


39

Ho lavorato allo sviluppo di applicazioni con molti sistemi di GUI "mantenuti" (di seguito maggiori informazioni su ciò che intendo con ciò) come MFC, QT, Forms, SWING e diversi framework Web-GUI alcuni anni fa. Ho sempre trovato i concetti della maggior parte dei sistemi di interfaccia grafica eccessivamente complicati e goffi. La quantità di eventi di callback, ascoltatori, copie di dati, qualcosa da stringere a qualcosa - le conversioni (e così via) sono sempre state una fonte di errori e mal di testa rispetto ad altre parti dell'applicazione. (Anche con un uso "corretto" di Data Binding / Modelli).

Ora sto scrivendo giochi per computer :). Finora ho lavorato con una GUI: Miyagi (non ben nota, ma sostanzialmente la stessa Idea di tutti gli altri sistemi.)

È stato orribile.

Per ambienti di rendering in tempo reale come Games, ho la sensazione che i sistemi di interfaccia grafica "conservati" siano ancora più obsoleti. Le interfacce utente di solito non devono essere auto-layout o avere finestre ridimensionabili al volo. Invece, devono interagire in modo molto efficiente con dati in continua evoluzione (come le posizioni 3d dei modelli nel mondo)

Un paio di anni fa, mi sono imbattuto in "IMGUI" che è sostanzialmente come una modalità grafica immediata, ma per le interfacce utente. Non ho prestato troppa attenzione, dato che ero ancora nello sviluppo di applicazioni e la scena IMGUI stessa sembrava non essere molto ampia o di successo. Tuttavia l'approccio che adottano sembra essere così totalmente sexy ed elegante, che mi ha fatto venire voglia di scrivere qualcosa per il prossimo progetto usando questo modo di interfaccia utente (non sono riuscito a convincere nessuno al lavoro: (...)

vorrei riassumere cosa intendo per "trattenuto" e "immediato":

Interfaccia grafica mantenuta: in una fase di inizializzazione separata, si creano "controlli della GUI" come etichette, pulsanti, caselle di testo ecc. E si utilizza un modo descrittivo (o programmatico) per posizionarli sullo schermo, tutto prima che venga riprodotto qualcosa. I controlli mantengono la maggior parte del proprio stato in memoria come X, posizione Y, dimensioni, bordi, controlli figlio, etichetta testo, immagini e così via. È possibile aggiungere callback e listener per essere informati sugli eventi e aggiornare i dati nel controllo della GUI.

GUI immediata: la libreria GUI è composta dalle funzioni "RenderButton", "RenderLabel", "RenderTextBox" ... (modifica: non confonderti dal Renderprefisso. Queste funzioni eseguono anche la logica dietro i controlli come il polling dell'input dell'utente, l'inserimento di caratteri, la gestione della velocità di ripetizione dei caratteri quando l'utente tiene premuto un tasto e così via ... che è possibile chiamare per eseguire il rendering "immediato" di un controllo (no devono essere immediatamente scritti nella GPU, di solito viene ricordato per il frame corrente e ordinato in lotti appropriati successivamente). La libreria non contiene alcun "stato" per questi. Se vuoi nascondere un pulsante ... non chiamare la funzione RenderButton. Tutte le funzioni di RenderXXX che hanno interazione dell'utente come pulsanti o caselle di controllo hanno valori di ritorno che indicano se l'utente ha fatto clic sul pulsante. Quindi il tuo "RenderGUI" sembra una grande funzione if / else in cui chiamate o meno le vostre funzioni RenderXXX a seconda del vostro stato di gioco e tutta la logica di aggiornamento dei dati (quando si preme un pulsante) viene interrotta nel flusso. Tutta l'archiviazione dei dati è "esterna" alla GUI e passata su richiesta alle funzioni di rendering. (Certo, divideresti le grandi funzioni in diverse funzioni o utilizzeresti alcune astrazioni di classe per raggruppare parti della GUI. Non scriviamo più codice come nel 1980, vero?;))

Ora ho scoperto che Unity3D utilizza effettivamente lo stesso approccio di base ai loro sistemi di GUI integrati. Probabilmente ci sono un paio di GUI con questo approccio anche là fuori?

Tuttavia ... quando ci guardiamo intorno, sembra esserci un forte pregiudizio nei confronti dei sistemi di GUI mantenuti? Almeno non ho trovato questo approccio se non in Unity3D e la comunità originale di IMGUI sembra essere piuttosto .... tranquilla.

Quindi qualcuno ha lavorato con entrambe le idee e ha un'opinione forte?

Modifica: sono più interessato alle opinioni che derivano dall'esperienza del mondo reale. Penso che ci siano molte discussioni accese nel forum IMGUI su qualsiasi "debolezza teorica" ​​dell'approccio immediato alla GUI, ma trovo sempre più illuminante conoscere le debolezze del mondo reale .



Grazie per il link Immagino che ti riferisci al commento di Kylotan . Interessante ..;)
Imi,

1
Ah, ho scritto a metà strada una risposta quando noto che la mia opinione è già stata vista ... tuttavia, la posterò comunque.
Kylotan,

2
È un peccato che queste domande vengano chiuse! Questo è il tipo di opinioni che sto cercando quando ho la stessa domanda.
Harald Scheirich,

Risposte:


34

Anzi. Ho svolto un lavoro retribuito con Gamingev su una terribile GUI di "modalità mantenuta" e su una terribile GUI di "modalità immediata" e sebbene entrambi mi abbiano fatto venire voglia di distogliere lo sguardo, l'approccio della modalità conservata è ancora chiaramente il migliore.

Gli svantaggi della modalità immediata sono molti:

  • non semplificano la configurazione del layout per artisti e designer;
  • ti fanno mescolare la logica con la presentazione;
  • rendono più difficile avere un unico modello di input coerente;
  • scoraggiano controlli complessi di dati dinamici (ad es. visualizzazioni elenco);
  • la stratificazione diventa molto imbarazzante (ad es. se chiamo RenderComboBox, la casella a discesa non può ancora essere visualizzata perché deve andare sopra il resto della finestra - lo stesso per i suggerimenti)
  • la configurazione dello stile di rendering termina con globals (ick) o argomenti con funzioni extra (ick);
  • le prestazioni possono essere scadenti perché chiamare tutte queste funzioni per interrogare valori che possono o meno essere cambiati tende a creare molti piccoli oggetti, sottolineando il gestore della memoria;
  • ... e non riesco nemmeno a immaginare quanto sia doloroso consentire a qualcuno di trascinare i bit intorno alla GUI e riordinarli. Dovresti mantenere una struttura di dati che ti dice dove eseguire il rendering di tutto, il che è molto simile a riscrivere tu stesso un sistema in modalità mantenuta.

Le GUI in modalità immediata sono allettanti per i programmatori solitari che desiderano un sistema HUD veloce e per questo sono fantastici. Per ogni altra cosa ... dì di no.


1
@ImmanuelScholz: Hai considerato che forse le GUI trattenute non sono in realtà "così brutte"?
Nicol Bolas,

1
Le librerie della GUI tendono ad essere ineleganti perché affrontano diverse preoccupazioni - input, rendering e accesso ai dati - e ognuna di queste è fortemente influenzata dal resto del programma. Ciò significa che le persone aggiungono livelli di astrazione per rendere riutilizzabile la GUI tra diversi programmi, dispositivi di input e renderer, al costo di renderla più complessa da usare.
Kylotan,

2
Aggiungete a ciò il fatto che non c'è consenso anche su come rendere le GUI in modalità mantenuta (MVC, MVP e MVVM sono 3 approcci popolari) o su come disporlo (dai dati? Dal codice?) O su come collegare il comportamento di input ( script inline, come nel Web? Segnali / slot nominati? Risultati sul posto come con IMGUI?) e questa mancanza di standardizzazione ha ostacolato lo sviluppo di One True Way per le GUI.
Kylotan,

2
La configurazione del layout di un artista richiede un editor, indipendentemente dal fatto che si stia utilizzando la GUI conservata o immediata. Questo punto non è completamente valido. La combinazione di logica e presentazione è la ragione per cui usi la GUI in modalità immediata, non è un difetto, è quello che vuoi, al contrario del disordine che viene mantenuto più GUI. Non capisci nemmeno molto. La configurazione non richiede globali o argomenti aggiuntivi se l'API è ben progettata. Ogni aspetto negativo che citi è risolvibile in una questione pulita. Ma soprattutto, stai scrivendo un'interfaccia utente del gioco, non Photoshop.
dreta,

3
@dreta: il mio punto sulla configurazione dell'artista è che ci sono cose che sono completamente poco pratiche da cambiare tramite un editor senza fondamentalmente scrivere il proprio livello di modalità conservato su di esso (ad es. cosa fare quando si fa clic su un pulsante o riordinare elementi). IMGUI funziona bene per effetti visivi molto semplici e banali, niente di più.
Kylotan,

31

Come qualcuno con cinque o sei anni di esperienza reale con IMGUI sul desktop, mi sento obbligato a difenderlo. Tutte le risposte (e la domanda stessa) si basano su una definizione molto limitata di IMGUI e sembrano esserci molte affermazioni discutibili.

Molto deriva dal presupposto che una libreria IMGUI non può conservare alcun dato nascosto. Questo non è affatto vero. Una sofisticata libreria IMGUI conserverà infatti la stessa quantità di dati di una equivalente libreria RMGUI. La differenza è che una libreria IMGUI memorizza principalmente i risultati nella cache , mentre una libreria RMGUI mantiene uno stato autorevole. In IMGUI, l'applicazione fornisce una funzione che accetta lo stato del modello corrente e produce una GUI per quello stato. Questa è la definizione autorevole della GUI. La libreria è responsabile di assicurarsi che la GUI sullo schermo corrisponda al risultato di quella funzione. Ciò non significa che debba valutare completamente quella funzione per ogni frame e ricostruire completamente la GUI. Questo è il punto di memorizzazione nella cache.

Con questa visione di IMGUI, puoi infatti realizzare layout avanzati e le prestazioni sono abbastanza ragionevoli. È inoltre possibile conservare lo stato autorevole reale se semplifica l'interfaccia. Lo scopo di IMGUI non è di fare in modo che l'applicazione mantenga tutto. Probabilmente l'applicazione non vuole archiviare la posizione di ogni barra di scorrimento e lo stato espanso / compresso di ogni nodo dell'albero. Il punto è di essere in grado di specificare proceduralmente il contenuto di quei nodi dell'albero e la loro stessa esistenza.

Esaminerei e risponderei a tutte le critiche dell'IMGUI punto per punto, ma non ne capisco davvero molte. La maggior parte di essi sembra derivare da una convinzione fondamentale che IMGUI sia un hacker e RMGUI sia ben strutturato, che immagino derivi dai suddetti malintesi. Non c'è motivo intrinseco che le librerie IMGUI debbano avere problemi con la complessità o debbano essere disseminate di globuli o mescolare la logica con la presentazione. Dirò che i vantaggi di IMGUI diventano meno importanti quanto più il tuo contenuto è guidato dall'artista, ma non sono sicuro del motivo per cui sarebbe effettivamente peggio per il contenuto guidato dall'artista. (Non utilizzo personalmente i contenuti guidati dall'artista, a parte i fogli di stile per cose come colori, dimensioni dei caratteri / bordi, ecc., Ma non vedo perché sia ​​più difficile da implementare rispetto a RMGUI.)

Nella mia mente, IMGUI è senza dubbio una buona cosa. Ti dà un modello molto migliore per il ragionamento sulla tua GUI. Diventa molto più funzionale e reattivo e minimizzi la quantità di stato mutevole su cui devi ragionare. D'altra parte, l'implementazione di una sofisticata libreria IMGUI è una vera sfida, e sicuramente più difficile dell'implementazione di una libreria RMGUI equivalente. È un compromesso tra complessità della libreria e complessità dell'applicazione. Se stai pensando di creare app complesse (o anche molte app semplici), il compromesso è molto buono. Se lo stai facendo per una singola app, ed è piuttosto semplice, probabilmente raggiungerai il tuo obiettivo più velocemente con RMGUI.

In ogni caso, buona fortuna!


5
"Non vi è alcuna ragione intrinseca che le librerie IMGUI debbano avere problemi con la complessità o debbano essere disseminate di globuli o mescolare la logica con la presentazione." È molto difficile vedere come si chiama il solito pulsante IMGUI, ad es. "if Button (x, y) then Action" non può essere chiamato mescolando la logica con la presentazione. Se non si passano i dettagli di rendering alla chiamata, non è possibile posizionarla o impostarla (tranne che con una globale o statica) e se non si elabora immediatamente la logica dei pulsanti, non si tratta in realtà di una GUI in modalità immediata. Potresti fornire un esempio da spiegare?
Kylotan,

4
Il contesto OpenGL è una grande fonte di bug a causa della quantità di stato condiviso, eppure anche con quell'API il passaggio è stato verso la modalità mantenuta nel corso degli anni perché la modalità immediata non offriva né la flessibilità né le prestazioni richieste.
Kylotan,

1
Non è la concorrenza che è il problema, sta avendo un grande blocco di stato che è condiviso. Le GUI in modalità conservata incapsulano lo stato rilevante con il controllo a cui si applica e tale incapsulamento viene generalmente considerato valido per motivi che non devono essere ripetuti qui. Le mie preoccupazioni specifiche sono elencate nella mia risposta sopra e non ho ancora visto alcun approccio IMGUI che non ne risenta.
Kylotan,

3
Un foglio di stile CSS si qualifica anche come "un grande blocco di stato condiviso"? In ogni caso, non so quale sia la tua particolare esperienza con IMGUI, ma se sei interessato ad approcci IMGUI che non soffrono di questi problemi, ti incoraggio a leggere la mia risposta sopra e a leggere il Forum IMGUI su Molly Rocket. È vero che non esiste una libreria IMGUI pronta per l'uso che puoi scaricare e iniziare a utilizzare in pochi minuti, ma se sei interessato a costruirne una, ci sono informazioni disponibili e persone disposte ad aiutare.
Tom,

1
I fogli di stile CSS sono statici; piuttosto diverso dai contesti OpenGL che sono estremamente dinamici!
Kylotan,

12

La libreria GUI è composta da funzioni "RenderButton", "RenderLabel", "RenderTextBox" ... che puoi chiamare per eseguire il rendering "immediatamente" di un controllo (non deve essere immediatamente scritto nella GPU. Di solito è ricordato per il frame corrente e ordinati in lotti appropriati successivamente).

Direi che questo non costituisce una libreria GUI. Sono solo alcune funzioni di rendering.

Il rendering della GUI è la parte più semplice della creazione di una GUI. Prendi ad esempio una casella di testo. Presumo il caso più semplice possibile: una semplice casella di testo per l'immissione di una riga.

RenderTextBoxdisegnerà solo una casella di testo. Farà alcune semplici misurazioni del testo e disegnerà i glifi sullo schermo. Sarà Non

  • Rileva che l'utente ha fatto clic con il mouse sul controllo e sposta il cursore nella posizione corretta nella stringa.
  • Rileva che l'utente ha fatto doppio clic con il mouse sul controllo e seleziona un blocco di testo.
  • Rileva che l'utente ha premuto il tasto "Home" e sposta il cursore nella parte anteriore del testo.
  • Rileva che l'utente ha premuto un tasto valido e modifica la stringa di conseguenza. Se il testo è stato selezionato, la parte selezionata verrà sostituita con il testo inserito.

Posso andare avanti, ma penso che il mio punto sia chiaro. Se vuoi usare RenderTextBoxper disegnare una casella di testo, otterrai solo una casella di testo statica e non funzionale. Qualsiasi funzionalità effettiva deve essere implementata da te.

Misurare il testo e disegnare glifi? Questa è la parte facile del lavoro della GUI. La GUI sta per "Interfaccia utente grafica". Le ultime due parole, in cui prendi input dall'utente e fai qualcosa con esso, sono la parte difficile.

I giocatori si aspettano che i controlli della GUI funzionino ragionevolmente. In un ambiente in stile PC (es. Mouse e tastiera), se i giocatori vedono una casella di testo, si aspettano che funzioni come una normale casella di testo. Si aspettano di essere in grado di spostarsi in esso con i tasti freccia, saltare in avanti e terminare con home ed eliminare, selezionare le lettere in esso, ecc.

Ciò significa che dovrai implementare tutto questo codice UI. Devi testare quale controllo è stato cliccato. Devi quindi fare qualcosa in base a quale controllo è stato cliccato. Devi avere il concetto di un controllo "attivo", quello che ottiene l'input da tastiera. Controlli diversi devono rispondere in modo diverso ai diversi tipi di interazione dell'utente.

Fondamentalmente, avrai bisogno di una TextBoxWindowlezione.

Supponiamo che tu stia implementando una schermata delle opzioni di gioco. Quindi hai i tuoi diversi gruppi di opzioni: gameplay, grafica, audio, controlli, ecc. Quindi hai un elenco di diversi gruppi sul lato sinistro dello schermo. Ogni gruppo visualizza una serie di controlli che l'utente può manipolare. Cosa succede quando l'utente preme il tasto Tab?

Bene, dipende da quale controllo è attivo. Se uno dei controlli di gruppo è attivo (è stato fatto clic più di recente), passa al gruppo successivo. Se invece uno dei controlli all'interno del gruppo è attivo, passa al controllo successivo in quel gruppo. Ecco come funziona il sistema.

Quindi, non solo un input da tastiera per il processo di controllo attivo, ma deve ora inserire qualsiasi input non elaborato nel controllo che lo possiede . O quello, o i controlli devono essere in una sorta di elenco collegato, in modo che possa andare avanti e indietro. Ciò significa che deve esserci un comportamento predefinito in ciascun controllo.

Sembra sempre più una GUI mantenuta, no? L'unica differenza è che ... sei tu a fare il duro lavoro. L'uso della GUI di qualcun altro dovrebbe essere un modo per fare meno lavoro. Ma lo sforzo necessario per far rispondere una GUI come previsto dall'utente non è banale.

Ricorda: l'interfaccia utente non è per te, è per i tuoi utenti . È per il giocatore. Dovrebbe comportarsi come si aspettano. E se non lo fa, allora hai fallito.

Le interfacce utente di solito non devono essere auto-layout o avere finestre ridimensionabili al volo.

Questo è un pensiero limitato e limitante.

Ho potuto dare la tiritera sui diversi giochi che hanno diverse esigenze di interfaccia utente, che alcuni giochi fanno bisogno di Windows ridimensionabili e così via. Ma c'è un problema molto più grande.

Il tuo tipo di pensiero porta al problema delle Battaglie spaziali gratuite.

Se non hai mai giocato a quel gioco, è un gioco economico, indipendente e molto pesante per la GUI. Il gameplay reale è tutto fatto nella GUI (è un tipo di gioco "imposta le unità e guardale combattere"). Il problema?

LA GUI NON PUO 'ESSERE RIVALUTATA!

Oh, va bene se stai usando un monitor normale o hai una vista normale. Ma se sei io, ad esempio, che gestisco un monitor ridicolmente enorme (uno così grande da avere Windows ridimensiona le dimensioni di tutto il testo in modo da poterlo effettivamente leggere), questo è terribile . Il testo è microscopico. Non c'è modo di cambiare la dimensione del carattere.

Certo, GSB è un gioco basato sulla GUI, quindi è assolutamente ingiustificabile per loro. Un gioco con interfaccia grafica può probabilmente cavarsela.

Non dare mai per scontato che il tuo utente guardi il suo gioco esattamente come te. Farlo è follia.

Avere un sistema GUI che può ridimensionare se stesso alla risoluzione dell'utente, una GUI veramente indipendente dalla risoluzione, richiede che il layout faccia parte del sistema stesso della GUI. Se non lo fornirai, il tuo testo apparirà minuscolo sul monitor gigante di qualcuno. Questa non è una buona cosa

Quindi direi che il tuo pensiero su questo argomento è miope. È cosa serve quella roba. È necessario ciò che le GUI conservate forniscono. Oh, potresti non aver bisogno di tutto ciò che fornisce un particolare sistema di interfaccia grafica. Ma ne hai bisogno.

Il lavoro sulla piastra di base che devi fare per ottenere i dati sul sistema è un piccolo prezzo da pagare accanto alla ragionevole garanzia che l'utente può interagire correttamente con i controlli e che si ridimensionerà per adattarsi alle esigenze del giocatore.

Potresti riuscire a cavartela con una GUI in modalità immediata se non ricevi molto input da parte del giocatore. Ma questo sarebbe tutto.


5
Per favore, non prenderla nel modo sbagliato, ma potrei chiederti di nuovo se parli per esperienza del mondo reale usando effettivamente un approccio GUI immediato nello sviluppo di un gioco (e mentre leggo la tua opinione: probabilmente sostituendolo a metà strada nello sviluppo) di frustrazione;))? A proposito: la funzionalità nella foto di una casella di testo può essere (ed è, ad esempio, in UnityGui.TextField) implementata all'interno della classe RenderTextBox. Inoltre, nulla nell'approccio della GUI immediata vieta al progettista della biblioteca di utilizzare le classi per i controlli della GUI, se appropriato. Solo l'uso sarebbe fondamentale diverso.
Imi,

1
@Immanuel: "A proposito: la funzionalità illustrata di una casella di testo può essere (ed è, ad esempio, in UnityGui.TextField) implementata all'interno della classe RenderTextBox." Hai detto che RenderTextBoxera una funzione , non una classe. Quindi la tua divisione tra "modalità immediata" e "modalità conservata" sembra essere intorno al luogo in cui sono archiviati i dati, non a chi li gestisce. In tal caso, è necessario rendere più chiara questa distinzione nella domanda, poiché suggerisce che una "GUI in modalità immediata" disegna semplicemente elementi sullo schermo. Che non può ottenere input (perché ciò richiederebbe uno stato persistente) e simili. Quindi che cos'è?
Nicol Bolas,

1
@ImmanuelScholz: "Non riesco a vedere un argomento contro un" approccio immediato della GUI "in questo" Pensavo di averlo spiegato abbastanza bene: qualcuno deve scrivere il codice . Qualcuno deve ottenere input, spostare il cursore, gestire un controllo corrente, gestire il layout, ecc. La descrizione di una "GUI in modalità immediata" perde tutto ciò, e tutto ciò è importante per qualsiasi cosa, salvo il più semplicistico basato sull'output GUI. Quindi non riesco a vedere il tuo argomento che "l'approccio GUI immediato" ha qualche pregi di sorta.
Nicol Bolas,

1
Scusa, colpa mia. "... implementato all'interno della funzione RenderTextBox" (non di classe). Si tratta di una funzione e fa input dell'utente processo e la libreria do contenere qualche stato (come controllo mirato corrente). Per favore, senza offesa, ma posso presumere che tu sappia solo "GUI immediata" dal mio post qui e che non hai mai guardato in IMGUI o Unity3D? Sicuramente non ho comprensibile descrivere ciò che una "GUI immediata" contiene in dettaglio qui, volevo solo riassumere quindi non stiamo parlando di cose totalmente diverse (ad esempio per non confonderci con la "modalità grafica immediata").
Imi,

2
@ImmanuelScholz: "Sicuramente non ho descritto in modo comprensibile cosa una" GUI immediata "contenga in dettaglio qui" Quindi la tua domanda è incompleta. In effetti, è piuttosto fuorviante, perché la "modalità immediata" implica una mancanza di stato. Il termine "mantenuto" deriva dal fatto che ha stato. Quindi se una "GUI in modalità immediata" mantiene lo stato ... non è la modalità immediata.
Nicol Bolas,

8

Qualche tempo fa anche IMGUIs ha attirato il mio interesse, come test ho scritto un paio di tutorial per familiarizzare con le tecniche (inizia qui se sei interessato, ma non è molto più di C # / XNA + il 'tutorial' originale qui ) .

Mi sono davvero piaciute le IMGUI per un po 'perché le informazioni che visualizzano sono sempre aggiornate e corrette (poiché non esiste uno stato in cui si alimentano sempre i dati effettivi). Ma alla fine ho perso interesse, quindi normalmente utilizzo nuovamente le GUI trattenute.

Alla fine ho pensato che l'immediatezza della GUI rendesse più difficile separare la GUI dai dati e, a volte, ho cercato di disaccoppiare di più le cose introducendo un certo stato, rompendo l'eleganza di IMGUI. Inoltre, non penso che scrivere codice per le GUI conservate sia più lavoro che scrivere codice per le IMGUI e mi piace che le GUI conservate possano essere attivate e dimenticate, e mi piacciono molto gli eventi :).

Tuttavia, ogni volta che qualcuno menziona IMGUI qualcosa dentro di me vuole riprovare, e cercare di fare meglio, perché c'è davvero un po 'di eleganza, non sono sicuro al 100% se renderà sempre più facile il tuo lavoro. Direi di provarlo, magari provare come ho fatto io e scrivere alcuni tutorial (trovo che il modo migliore per imparare nuove tecniche sia spiegandole ad altri).


8

Ho lavorato molto con il sistema GUI di Unity3D, che funziona esattamente come hai descritto. E devo dire che lo odio con passione.

L'approccio "immediato" funziona davvero bene in alcuni casi. Innanzitutto, quando hai solo bisogno di un paio di pulsanti ed etichette, ad esempio, pensa allo sparatutto HUD. La loro creazione con un approccio "mantenuto" non è molto difficile, ma è semplicissima con UnityGUI. Il secondo caso è quando devi riempire molti controlli sullo schermo, ma non ti interessa davvero il layout. Soprattutto quando i controlli esatti sono noti solo in fase di esecuzione. Questo in realtà non è utile in nessun gioco, ma è molto utile quando si eseguono strumenti all'interno dell'editor Unity.

Tuttavia, qualsiasi interfaccia grafica semi-complessa - per esempio un gioco di ruolo (MMO) o un gioco di strategia, ad esempio - si trasforma inevitabilmente in un orribile pasticcio di codice indecifrabile, pieno di casi speciali e in molti modi diversi. Quando crei una tale GUI, di solito hai un layout piuttosto specifico che deve funzionare per qualsiasi risoluzione ed essere in grado di mostrare tutti i dati che invii. Hai bisogno di cose come, ad esempio, spostare alcuni pulsanti in basso per far spazio a testi più lunghi. Con la GUI "mantenuta", puoi avere un controllo che lo fa automaticamente. Con la modalità "immediata", non ci sono controlli, quindi devi fare tutto in modo esplicito.

Un altro problema con UnityGUI (non sono sicuro che accada a tutte le GUI in modalità immediata) è che, ad esempio, una Button()chiamata funziona senza considerare altre chiamate GUI. Quindi, se un pulsante si trova sopra l'altro, un clic premi entrambi i pulsanti contemporaneamente. Questo non è sicuramente ciò che l'utente si aspetta, quindi questo aggiunge un altro caso speciale da gestire.

Per convivere con tutto ciò, ho sempre scritto il mio wrapper su UnityGUI che lo trasforma in un sistema in modalità "conservato": controlli che memorizzano il loro stato e chiamano semplicemente le GUIfunzioni richieste in ogni frame per me.

Non posso dire che la modalità "immediata" sia decisamente peggiore di "mantenuta", ma certamente mi sento molto meglio lavorando in modalità "mantenuta".


1
Sì, ho riscontrato tutti questi problemi con la GUI di Unity e di conseguenza l'odio. È ottimo per gli HUD statici rapidi ma una vera seccatura per qualsiasi altra cosa.
Kylotan,

7

Ho intenzione di difendere IMGUI qui perché alcuni dei problemi elencati in precedenza possono essere risolti se si è disposti a scrivere il codice per questo. Inoltre, se si scrive il codice per esso, si dispone di una libreria robusta che è riutilizzabile e richiede raramente modifiche.

  • caricamento della GUI dallo schema

forse all'inizio sembra che gli artisti non abbiano molta flessibilità con IMGUI, questo è risolto o migliorato con il caricamento del layout della GUI da uno schema xml o JSON.

  • menu layer disegna chiamate

questo problema è risolto con l'ordinamento, è necessario creare la classe UI Manager che ordina l'ordine di disegno, ho risolto questo problema in C # XNA con pannelli mobili e cliccabili che si disegnano uno sopra l'altro. Posso inviare pseudo codice se richiesto.

  • caselle di riepilogo

puoi disegnare stringhe da un array? puoi definire le aree rettangolari dall'altezza e dalla larghezza dei caratteri di quelle stringhe? puoi creare un rapporto tra le dimensioni del tuo pulsante di scorrimento e l'altezza di tutti quei rettangoli sommati? Quindi sei a metà strada per creare una casella di riepilogo con un pulsante scorrevole per spostarti in alto o in basso. Ho pensato che sarebbe stato difficile, ma si è rivelato molto più semplice di quanto pensassi. nessun buffer, nessuno stato, nessun callback coinvolti.

  • separando i dati dalla GUI

non lasciare che i singoli pannelli, pulsanti, caselle contengano i dati. So che al mio primo tentativo di IMGUI fu immediato ma solo in senso grafico. Ho commesso l'errore di conservare i dati sull'interfaccia utente. È stato quasi un cambiamento filosofico pensare in modo diverso su dove posizionare e modificare i dati tramite i cambiamenti dell'interfaccia utente.

  • GUI dagli SDK

questo è il limite e la funzionalità del codice dell'SDK, non il tuo. Trovo che l'interfaccia utente dell'SDK (Hammer, Unity, UDK) sia quasi una nuova lingua da imparare comunque. In effetti sono simili a me come Windows.Forms, entrambi sono impostati per la più ampia possibilità e quindi hanno un peso extra nella complessità.

e infine guarda questo> http://mollyrocket.com/861


4

Le interfacce utente di solito non devono essere auto-layout o avere finestre ridimensionabili al volo. Invece, devono interagire in modo molto efficiente con dati in continua evoluzione (come le posizioni 3d dei modelli nel mondo)

Dipende dal genere e dal gioco in questione. Un buon sistema di gestione dell'inventario è vitale per la maggior parte dei giochi di ruolo. Desidererai qualcosa che gestisca i layout per te, supporti le barre di scorrimento, il trascinamento della selezione, i suggerimenti e altre funzionalità molto più facili da implementare utilizzando la GUI mantenuta.

Non riesco a pensare a un modo per trascinare e rilasciare con una GUI immediata che non richiede molta giocoleria o salvataggio dello stato dell'utente come la modifica temporanea del buffer Z e l'archiviazione delle informazioni temporali per escludere un clic che è accaduto per spostare un po.

Ma dal punto di vista del design ho difficoltà a immaginare un mondo senza i miei eventi della GUI. Inoltre una GUI immediata non è compatibile con OOP, costringendoti a ricorrere alla programmazione procedurale.

La semplicità offerta dalle GUI immediate comporta un costo aggiuntivo per la complessità del codice che aumenta rapidamente man mano che aumenta la complessità richiesta dall'interfaccia utente; dove come una buona GUI mantenuta è originariamente più complessa ma si ridimensiona meglio. Quindi, al di sotto di un certo punto di complessità, una GUI immediata è adeguata, ma per la maggior parte delle situazioni preferirei una GUI mantenuta.


1
Voglio chiederti: la tua opinione proviene dall'esperienza reale del mondo reale o dal pensiero teorico guardando entrambi i sistemi? Uhm .. questo suona più duro del previsto, scusa. Quello che voglio dire è: condivido la tua opinione e valutazione da un aspetto teorico . I sistemi simil-IMGUI probabilmente portano a meno codice OOPish (se questo è un problema), hanno problemi con i controlli che richiedono un certo stato e così via. È solo che ... i normali sistemi di interfaccia grafica sono anche molto grandi e complessi già da soli, quindi hai molta complessità da aggiungere fino a quando non ti avvicini a questi sistemi ..
Imi,

1
Immanuel, non è necessario avere un'esperienza di sviluppo nel mondo reale per sapere che molti giochi richiedono il layout automatico e finestre ridimensionabili.
Kylotan,

1
@Immanuel Scholz Ammetto di avere molta più esperienza con le UI conservate; mantenendo uno come progetto OSS e avendo lavorato con loro anche se il mio corriere (che certamente è molto giovane). Tuttavia, ho usato il sistema UI di Unity3D e l'ho duplicato quando mi sono trasferito su XNA. La mia UI mantenuta è stata sviluppata perché mi sono stancato di copiare lo stesso hack da un progetto all'altro per ottenere una funzionalità uniforme.
ClassicThunder

@Kylotan per "finestre ridimensionabili" Voglio dire che puoi ridimensionare attivamente gli elementi dell'interfaccia utente trascinandoli (o altri mezzi) e con il layout automatico che quando li ridimensioni, l'interfaccia utente si adatta in un modo "carino" come visualizzare le barre di scorrimento, allocando più linee per le barre dei pulsanti e così via. Sì, a volte lo vedo nei giochi ma è molto più comune nelle applicazioni desktop. Inoltre, penso che rendere le buone UI ridimensionabili non sia la cosa più semplice per i sistemi di GUI conservati.
Imi,

1
Le finestre ridimensionabili e il layout automatico sono praticamente la stessa cosa. Nelle GUI in modalità mantenuta ogni controllo conosce le sue dimensioni (indipendentemente dal fatto che cambi in runtine o meno) e l'autolayout è fondamentalmente un controllo delle dimensioni ricorsivo. Probabilmente è più importante nei giochi rispetto alle app desktop perché ci aspettiamo GUI a schermo intero in una varietà di rapporti d'aspetto e su piattaforme diverse.
Kylotan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.