GUI inmediata: ¿sí o no? [cerrado]

39

He estado trabajando en el desarrollo de aplicaciones con muchos sistemas GUI "retenidos" (a continuación, más sobre lo que quiero decir con eso) como MFC, QT, Forms, SWING y varios marcos de GUI web hace algunos años. Siempre encontré los conceptos de la mayoría de los sistemas GUI demasiado complicados y torpes. La cantidad de eventos de devolución de llamada, oyentes, copias de datos, algo para encadenar a algo: las conversiones (y así sucesivamente) siempre fueron una fuente de errores y dolores de cabeza en comparación con otras partes de la aplicación. (Incluso con el uso "adecuado" de enlaces / modelos de datos).

Ahora estoy escribiendo juegos de computadora :). Trabajé con una GUI hasta ahora: Miyagi (no conocida, pero básicamente la misma Idea que todos los demás sistemas).

Fue horrible.

Para entornos de renderizado en tiempo real como Juegos, tengo la sensación de que los sistemas GUI "retenidos" son aún más obsoletos. Por lo general, las interfaces de usuario no necesitan tener un diseño automático o tener ventanas redimensionables sobre la marcha. En cambio, necesitan interactuar de manera muy eficiente con datos que cambian constantemente (como las posiciones 3D de modelos en el mundo)

Hace un par de años, me topé con "IMGUI", que es básicamente como un modo de gráficos inmediatos, pero para las interfaces de usuario. No presté demasiada atención, ya que todavía estaba en desarrollo de aplicaciones y la escena IMGUI en sí misma parecía no ser realmente amplia ni exitosa. Aún así, el enfoque que adoptan parece ser tan completamente sexy y elegante, que me hizo querer escribir algo para el próximo proyecto utilizando esta forma de interfaz de usuario (no logré convencer a nadie en el trabajo: (...)

permítanme resumir lo que quiero decir con "retenido" e "inmediato":

GUI retenida: en una fase de inicialización separada, crea "controles GUI" como etiquetas, botones, cuadros de texto, etc. y usa alguna forma descriptiva (o programática) de colocarlos en la pantalla, todo antes de que se muestre algo. Los controles contienen la mayor parte de su propio estado en la memoria, como ubicación X, Y, tamaño, bordes, controles secundarios, texto de etiqueta, imágenes, etc. Puede agregar devoluciones de llamada y escuchas para informarse de los eventos y actualizar los datos en el control de la GUI.

GUI inmediata: la biblioteca GUI consta de funciones "RenderButton", "RenderLabel", "RenderTextBox" ... de un solo disparo (editar: no se confunda con el Renderprefijo. Estas funciones también hacen la lógica detrás de los controles, como sondear la entrada del usuario, insertar caracteres, manejar la velocidad de repetición de caracteres cuando el usuario mantiene presionada una tecla y así sucesivamente ...) que puede llamar para representar "inmediatamente" un control (no no debe escribirse de inmediato en la GPU. Por lo general, se recuerda para el marco actual y se clasifica en lotes apropiados más adelante). La biblioteca no tiene ningún "estado" para estos. Si desea ocultar un botón ... simplemente no llame a la función RenderButton. Todas las funciones de RenderXXX que tienen interacción del usuario como botones o casillas de verificación tienen valores de retorno que indican si, por ejemplo, el usuario hizo clic en el botón. Entonces tu "RenderGUI" La función se ve como una gran función if / else donde llamas o no a tus funciones RenderXXX dependiendo del estado de tu juego y toda la lógica de actualización de datos (cuando se presiona un botón) se intermanga en el flujo. Todo el almacenamiento de datos está "fuera" de la interfaz gráfica de usuario y se pasa a pedido a las funciones de Render. (Por supuesto, dividiría las grandes funciones en varias o usaría algunas abstracciones de clase para agrupar partes de la interfaz gráfica de usuario. Ya no escribimos código como en 1980, ¿verdad?)

Ahora descubrí que Unity3D en realidad usa el mismo enfoque básico para sus sistemas GUI integrados. ¿Probablemente también haya un par de GUI con este enfoque?

Aún así ... al mirar alrededor, ¿parece haber un fuerte sesgo hacia los sistemas GUI retenidos? Al menos no he encontrado este enfoque, excepto en Unity3D y la comunidad IMGUI original parece ser bastante ... tranquila.

Entonces, ¿alguien trabajó con ambas ideas y tiene alguna opinión sólida?

Editar: Estoy más interesado en las opiniones que surgen de la experiencia del mundo real. Creo que hay muchas discusiones acaloradas en el foro IMGUI sobre cualquier "debilidad teórica" ​​del enfoque inmediato de GUI, pero siempre encuentro más esclarecedor saber sobre las debilidades del mundo real .

Imi
fuente
Gracias por el enlace. Creo que te estás refiriendo al comentario de Kylotan . Interesante ..;)
Imi
1
Hah, estaba a mitad de camino de escribir una respuesta a continuación cuando noté que mi opinión ya se había visto ... aún así, la publicaré de todos modos.
Kylotan
2
¡Es una pena que estas preguntas se estén cerrando! Este es el tipo de opiniones que busco cuando tengo la misma pregunta.
Harald Scheirich

Respuestas:

34

No. He realizado un trabajo de gamedev pagado en una horrible GUI de 'modo retenido' y en una horrible GUI de 'modo inmediato' y aunque ambos me hicieron querer arrancarme los ojos, el enfoque del modo retenido sigue siendo claramente el mejor.

Las desventajas del modo inmediato son muchas:

  • no facilitan a los artistas y diseñadores configurar el diseño;
  • te hacen mezclar lógica con presentación;
  • hacen que sea más difícil tener un solo modelo de entrada consistente;
  • desalientan controles complejos de datos dinámicos (por ejemplo, vistas de lista);
  • las capas se vuelven muy incómodas (por ejemplo, si llamo a RenderComboBox, el cuadro desplegable aún no puede renderizarse porque necesita ir por encima del resto de la ventana, lo mismo para la información sobre herramientas) l
  • la configuración del estilo de renderizado termina haciéndose con globales (ick) o argumentos de funciones adicionales (ick);
  • el rendimiento puede ser pobre porque llamar a todas estas funciones para consultar valores que pueden o no haber cambiado tiende a crear muchos objetos pequeños, lo que estresa al administrador de memoria;
  • ... y ni siquiera puedo imaginar lo doloroso que sería permitir que alguien arrastre bits de la GUI y los vuelva a ordenar. Tendría que mantener una estructura de datos que le diga dónde renderizar todo, que es muy similar a reescribir un sistema de modo retenido usted mismo.

Las GUI de modo inmediato son tentadoras para programadores solitarios que desean un sistema HUD rápido, y para ese propósito son geniales. Para cualquier otra cosa ... solo di que no.

Kylotan
fuente
1
@ImmanuelScholz: ¿Has considerado que quizás las GUI retenidas no son realmente "tan feas"?
Nicol Bolas
1
Las bibliotecas GUI tienden a ser poco elegantes porque abordan varias inquietudes (entrada, representación y acceso a datos) y cada una de ellas está fuertemente influenciada por el resto del programa. Esto significa que las personas agregan capas de abstracción para hacer que la GUI sea reutilizable en diferentes programas, dispositivos de entrada y renderizadores, a costa de hacerla más compleja de usar.
Kylotan
2
Agregue a eso el hecho de que no hay consenso ni siquiera sobre cómo hacer que las GUI en modo retenido (MVC, MVP y MVVM sean 3 enfoques populares) o cómo establecerlo (¿desde datos? ¿Desde código?) O cómo adjuntar el comportamiento de entrada ( secuencia de comandos en línea, como con la Web? Señales / ranuras con nombre? ¿Resultados en el lugar como con IMGUI?) y esta falta de estandarización ha obstaculizado el desarrollo de One True Way para GUI.
Kylotan
2
La configuración del diseño por un artista requiere un editor sin importar si está utilizando una GUI retenida o inmediata. Este punto es completamente inválido. La combinación de lógica y presentación es la razón por la que usa la GUI de modo inmediato, eso no es un defecto, es lo que desea, en lugar del desorden que se retiene más GUI. Ni siquiera entiendes tanto. La configuración no requiere argumentos globales o argumentos adicionales si la API está bien diseñada. Todos los inconvenientes que mencionas se pueden resolver de forma limpia. Sin embargo, lo más importante es que estás escribiendo una interfaz de usuario de juego, no Photoshop.
Dreta
3
@dreta: mi punto sobre la configuración del artista es que hay cosas que son completamente poco prácticas para cambiar a través de un editor sin básicamente escribir su propia capa de modo retenido encima (por ejemplo, qué hacer cuando se hace clic en un botón o reordenar elementos). IMGUI funciona bien para imágenes muy simples y triviales, nada más.
Kylotan
31

Como alguien con cinco o seis años de experiencia real con IMGUI en el escritorio, me siento obligado a defenderlo. Todas las respuestas (y la pregunta en sí) se basan en una definición muy restringida de IMGUI, y parece haber muchas afirmaciones cuestionables.

Mucho de esto se origina en el supuesto de que una biblioteca IMGUI no puede retener ningún dato oculto. Esto no es cierto en absoluto. De hecho, una sofisticada biblioteca IMGUI retendrá casi tantos datos como una biblioteca RMGUI equivalente. La diferencia es que una biblioteca IMGUI almacena principalmente resultados en caché , mientras que una biblioteca RMGUI mantiene un estado autorizado. En IMGUI, la aplicación proporciona una función que toma el estado actual del modelo y produce una GUI para ese estado. Esta es la definición autorizada de la GUI. La biblioteca es responsable de asegurarse de que la GUI en pantalla coincida con el resultado de esa función. Esto no significa que deba evaluar completamente esa función en cada marco y reconstruir completamente la GUI. Ese es el punto de almacenamiento en caché.

Con esta vista de IMGUI, de hecho puede hacer un diseño avanzado, y el rendimiento es bastante razonable. También puede conservar el estado autoritario real si facilita la interfaz. El objetivo de IMGUI no es hacer que la aplicación retenga todo. La aplicación probablemente no quiera tener que almacenar la posición de cada barra de desplazamiento y el estado expandido / colapsado de cada nodo del árbol. El punto es poder especificar procesalmente el contenido de esos nodos de árbol y su propia existencia.

Revisaría y respondería a todas las críticas de IMGUI punto por punto, pero realmente no entiendo muchas de ellas. La mayoría de ellos parecen provenir de una creencia fundamental de que IMGUI es hack y RMGUI está bien estructurado, lo que supongo que se deriva de los malentendidos anteriores. No hay una razón inherente para que las bibliotecas IMGUI tengan problemas con la complejidad o tengan que estar llenas de globales o mezclar lógica con presentación. Diré que las ventajas de IMGUI se vuelven menos importantes cuanto más contenido esté dirigido por artistas, pero no estoy seguro de por qué en realidad sería peor para el contenido dirigido por artistas. (Yo personalmente no uso contenido dirigido por artistas, aparte de las hojas de estilo para cosas como colores, tamaños de fuente / borde, etc., pero no veo por qué sería más difícil de implementar que para RMGUI).

En mi opinión, IMGUI es, sin duda, algo bueno. Le da un modelo mucho mejor para razonar sobre su GUI. Se vuelve mucho más funcional y reactivo, y minimiza la cantidad de estado mutable sobre el que tiene que razonar. Por otro lado, implementar una sofisticada biblioteca IMGUI es todo un desafío, y definitivamente más difícil que implementar una biblioteca RMGUI equivalente. Es una compensación entre la complejidad de la biblioteca y la complejidad de la aplicación. Si planea crear aplicaciones complejas (o incluso muchas aplicaciones simples), la compensación es muy buena. Si está haciendo esto para una sola aplicación, y es bastante simple, probablemente alcanzará su objetivo más rápido con RMGUI.

en cualquier caso, buena suerte!

Tom
fuente
55
"No hay una razón inherente para que las bibliotecas IMGUI tengan problemas con la complejidad o tengan que estar llenas de globales o mezclar la lógica con la presentación". Es muy difícil ver cómo se llama el botón IMGUI habitual, por ejemplo. "if Button (x, y) then Action" no se puede llamar lógica de mezcla con presentación. Si no pasa detalles de representación a la llamada, entonces no puede posicionarla o aplicarle estilo (excepto con un global o estático), y si no procesa la lógica del botón de inmediato, entonces no es realmente una GUI de modo inmediato. ¿Podría dar un ejemplo para explicar?
Kylotan
44
El contexto de OpenGL es una gran fuente de errores debido a la cantidad de estado compartido, y sin embargo, incluso con esa API, el movimiento ha sido hacia el modo retenido a lo largo de los años porque el modo inmediato no ofrecía la flexibilidad o el rendimiento requerido.
Kylotan
1
El problema no es la concurrencia, es tener un gran bloque de estado que se comparte. Las GUI de modo retenido encapsulan el estado relevante con el control al que se aplica, y dicha encapsulación generalmente se considera buena por razones que no necesitan repetirse aquí. Mis inquietudes específicas se enumeran en mi respuesta anterior y aún no he visto ningún enfoque IMGUI que no las sufra todas.
Kylotan
3
¿Una hoja de estilo CSS también califica como "un gran bloque de estado que se comparte"? En cualquier caso, no sé cuál es su experiencia particular con IMGUI, pero si está interesado en los enfoques de IMGUI que no sufren esos problemas, le animo a que lea mi respuesta anterior y lea el Foro IMGUI sobre Molly Rocket. Es cierto que no hay una biblioteca IMGUI lista para usar que pueda descargar y comenzar a usar en minutos, pero si está interesado en crear una, hay información disponible y personas dispuestas a ayudar.
Tom
1
Las hojas de estilo CSS son de estado estático; ¡bastante diferente de los contextos de OpenGL que son extremadamente dinámicos!
Kylotan
12

La biblioteca de la GUI consta de "RenderButton", "RenderLabel", "RenderTextBox" ... funciones a las que puede llamar para representar "inmediatamente" un control (no tiene que escribirse inmediatamente en la GPU. Por lo general, se recuerda para el marco actual y ordenado en lotes apropiados más tarde).

Me atrevería a decir que esto no constituye una biblioteca GUI. Es solo un montón de funciones de renderizado.

Renderizar la GUI es la parte más fácil de hacer una GUI. Tome un cuadro de texto, por ejemplo. Asumiré el caso más fácil posible: un simple cuadro de texto de entrada de una sola línea.

RenderTextBoxsolo dibujará un cuadro de texto. Hará una medición de texto simple y dibujará los glifos en la pantalla. Lo hará sin

  • Detecte que el usuario ha hecho clic con el mouse en el control y mueva el cursor a la ubicación adecuada en la cadena.
  • Detecta que el usuario hizo doble clic con el mouse en el control y selecciona un bloque de texto.
  • Detecta que el usuario presionó la tecla "Inicio" y mueve el cursor al frente del texto.
  • Detecta que el usuario presionó una tecla válida y modifica la cadena en consecuencia. Si se seleccionó texto, la parte seleccionada se reemplazará con el texto insertado.

Puedo seguir, pero creo que mi punto es claro. Si desea utilizar RenderTextBoxpara dibujar un cuadro de texto, todo lo que obtendrá es un cuadro de texto estático, no funcional. Cualquier funcionalidad real debe ser implementada por usted.

¿Medición de texto y dibujo de glifos? Esa es la parte fácil del trabajo de la GUI. GUI significa "interfaz gráfica de usuario". Las dos últimas palabras, en las que tomas información del usuario y haces algo con ella, son la parte difícil.

Los jugadores del juego esperan que los controles GUI funcionen razonablemente. En un entorno de estilo PC (es decir, mouse y teclado), si los jugadores ven un cuadro de texto, esperan que funcione como un cuadro de texto normal. Esperan poder moverse con teclas de flecha, saltar al frente y terminar con inicio y borrar, seleccionar letras, etc.

Eso significa que tendrá que implementar todo este código de interfaz de usuario. Tienes que probar en qué control se hizo clic. Luego debe hacer algo en función del control en el que se hizo clic. Debe tener el concepto de un control "activo", el que recibe la entrada del teclado. Los diferentes controles deben responder de manera diferente a los diferentes tipos de interacción del usuario.

Básicamente, vas a necesitar una TextBoxWindowclase.

Digamos que estás implementando una pantalla de opciones de juego. Entonces tiene sus diferentes grupos de opciones: jugabilidad, gráficos, sonido, controles, etc. Así que tiene una lista de diferentes grupos en el lado izquierdo de la pantalla. Cada grupo muestra una serie de controles que el usuario puede manipular. ¿Qué sucede cuando el usuario presiona la tecla Tab?

Bueno, depende de qué control esté activo. Si uno de los controles de grupo está activo (se hizo clic más recientemente), se mueve al siguiente grupo. Si, en cambio, uno de los controles dentro del grupo está activo, entonces se mueve al siguiente control en ese grupo. Así es como se pretende que funcione el sistema.

Por lo tanto, una entrada de teclado de proceso de control activo no solo debe, sino que también debe almacenar cualquier entrada no procesada en el control que la posee . O eso, o los controles deben estar en algún tipo de lista vinculada, para que pueda ir y venir. Eso significa que debe haber un comportamiento predeterminado en cada control.

Esto suena cada vez más como una GUI retenida, ¿no? La única diferencia es que ... eres el que hace el trabajo duro. Se supone que usar la GUI de otra persona es una forma de hacer menos trabajo. Pero el esfuerzo que lleva hacer que una GUI responda como el usuario espera no es trivial.

Recuerde: la interfaz de usuario no es para usted, es para sus usuarios . Es para el jugador. Debería comportarse como lo esperan. Y si no es así, entonces has fallado.

Las interfaces de usuario generalmente no necesitan un diseño automático o tener ventanas redimensionables sobre la marcha.

Ese es un pensamiento limitado y limitante.

Podría dar la perorata sobre los diferentes juegos que tienen diferentes necesidades de interfaz de usuario, que algunos juegos hacen necesidad ventanas de tamaño variable y así sucesivamente. Pero hay un problema mucho mayor.

Tu tipo de pensamiento conduce al problema de las batallas espaciales gratuitas.

Si nunca has jugado ese juego, es un juego barato, independiente y con mucha interfaz gráfica de usuario. La jugabilidad real se realiza en la GUI (es un tipo de juego de "configurar las unidades y verlas pelear"). ¿El problema?

¡LA GUI NO PUEDE SER RESCALADA!

Oh, esto está bien si estás usando un monitor normal o tienes una vista normal. Pero si eres yo, por ejemplo, quien ejecuta un monitor ridículamente grande (uno tan grande que tienes a Windows escalando el tamaño de todo el texto para que realmente puedas leerlo), esto es terrible . El texto es microscópico. No hay forma de cambiar el tamaño de fuente.

Por supuesto, GSB es un juego basado en GUI, por lo que es absolutamente inexcusable para ellos. Un juego GUI-lite probablemente puede salirse con la suya.

Nunca asumas que tu usuario está viendo su juego exactamente como tú. Hacer eso es una locura.

Tener un sistema GUI que pueda reescalarse a la resolución del usuario, una GUI verdaderamente independiente de la resolución, requiere que el diseño sea parte del propio sistema GUI. Si no va a proporcionar eso, entonces su texto aparecerá pequeño en el monitor gigante de alguien. Esto no es algo bueno.

Entonces diría que su pensamiento sobre este tema es miope. Usted no necesita esas cosas. Necesita lo que proporcionan las GUI retenidas. Es posible que no necesite todo lo que proporciona un sistema GUI en particular. Pero necesitas algo de eso.

El trabajo repetitivo que necesita hacer para llevar los datos al sistema es un pequeño precio a pagar además de tener una seguridad razonable de que el usuario puede interactuar con los controles correctamente y que se redimensionará para adaptarse a las necesidades del jugador.

Es posible que pueda salirse con una GUI de modo inmediato si no recibe mucha información del usuario del reproductor. Pero eso sería todo.

Nicol Bolas
fuente
55
Por favor, no lo tomes a mal, pero puedo preguntarte nuevamente si hablas de la experiencia del mundo real con el uso de un enfoque GUI inmediato en el desarrollo de un juego (y como leí tu opinión: probablemente lo reemplace a mitad del desarrollo) de frustración;))? Por cierto: la funcionalidad ilustrada de un cuadro de texto puede implementarse (y, por ejemplo, en UnityGui.TextField) dentro de la clase RenderTextBox. Además, nada en el enfoque de GUI Inmediato prohíbe al diseñador de la biblioteca usar clases para controles de GUI, si es apropiado. Solo el uso sería fundamentalmente diferente.
Imi
1
@Immanuel: "Por cierto: la funcionalidad representada de un cuadro de texto puede implementarse (y, por ejemplo, en UnityGui.TextField) en la clase RenderTextBox". Dijiste que RenderTextBoxera una función , no una clase. Por lo tanto, su división entre "modo inmediato" y "modo retenido" parece estar en torno a dónde se almacenan los datos, no quién los administra. Si es así, debe aclarar esa distinción en su pregunta, porque sugiere que una "GUI de modo inmediato" simplemente dibuja cosas en la pantalla. Que no puede obtener información (porque eso requeriría un estado persistente) y tal. Entonces cual es?
Nicol Bolas
1
@ImmanuelScholz: "No veo un argumento en contra de un" Enfoque de GUI Inmediato "en este" Pensé que lo había explicado bastante bien: alguien tiene que escribir el código . Alguien tiene que obtener información, mover el cursor, administrar un control actual, manejar el diseño, etc. Su descripción de una "GUI de modo inmediato" pierde todo eso, y todo eso es importante para cualquier cosa, excepto el más simple basado en resultados GUI Por lo tanto, no veo su argumento de que el "enfoque de GUI inmediato" tiene alguna ventaja .
Nicol Bolas
1
Disculpa, mi error. "... implementado dentro de la función RenderTextBox" (no clase). Que es una función y hace la entrada del usuario y proceso de la biblioteca estén en posesión de algún estado (como el control de foco actual). Por favor, no intente ofender, pero ¿puedo suponer que solo conoce la "GUI inmediata" de mi publicación aquí y que no ha investigado la interfaz gráfica de usuario de IMGUI o Unity3D? Seguramente no comprendí lo que una "GUI inmediata" contiene en detalle aquí, solo quería resumir para que no estemos hablando de cosas totalmente diferentes (por ejemplo, no confundirnos con el "modo gráfico inmediato").
Imi
2
@ImmanuelScholz: "Seguramente no entendí lo que una" GUI inmediata "contiene en detalle aquí" Entonces su pregunta está incompleta. De hecho, es bastante engañoso, porque el "modo inmediato" implica una falta de estado. El término "retenido" proviene del hecho de que tiene estado. Entonces, si un "modo inmediato GUI" retiene el estado ... no es modo inmediato.
Nicol Bolas
8

Hace un tiempo, las IMGUI también me llamaron la atención, como prueba escribí un par de tutoriales para familiarizarme con las técnicas (comience aquí si está interesado, pero no es mucho más que C # / XNA + el 'tutorial' original aquí ) .

Realmente me gustaron las IMGUI por un corto tiempo porque la información que muestran siempre está actualizada y es correcta (ya que no hay un estado que siempre alimente a los datos reales). Pero al final perdí interés, así que normalmente ahora uso GUI retenidas nuevamente.

Al final, pensé que la inmediatez de la GUI hizo que fuera más difícil separar la GUI de los datos y, a veces, traté de desacoplar más las cosas introduciendo algún estado, rompiendo la elegancia de las IMGUI. Tampoco creo que escribir código para GUI retenidas sea más trabajo que escribir código para IMGUI y me gusta que las GUI retenidas se puedan disparar y olvidar, y realmente me gustan los eventos :).

Sin embargo, cada vez que alguien menciona IMGUIs, algo dentro de mí quiere volver a intentarlo, y se esfuerza más para hacerlo bien, porque realmente hay algo de elegancia allí, simplemente no estoy 100% seguro de si siempre hará su trabajo más fácil. Yo diría que lo pruebe, tal vez lo intente como lo hice y escriba algunos tutoriales (creo que la mejor manera de aprender nuevas técnicas es explicándolas a los demás).

Roy T.
fuente
8

Trabajé mucho con el sistema Unity3D GUI, que funciona tal como lo describiste. Y debo decir que lo odio con pasión.

El enfoque "inmediato" funciona realmente bien en algunos casos. Primero, cuando solo necesita un par de botones y etiquetas, por ejemplo, piense en el tirador HUD. Crearlos con un enfoque "retenido" no es muy difícil, pero es muy fácil con UnityGUI. El segundo caso es cuando necesita introducir muchos controles en la pantalla, pero realmente no le importa el diseño. Especialmente cuando los controles exactos solo se conocen en tiempo de ejecución. Esto no es realmente útil en ningún juego, pero es realmente útil al hacer que las herramientas se ejecuten dentro del editor de Unity.

Sin embargo, cualquier GUI de medio complejo, para un juego de rol (MMO) o un juego de estrategia, por ejemplo, inevitablemente se convierte en un horrible desastre de código indescifrable, lleno de casos especiales y rompiendo de muchas maneras. Al crear una GUI de este tipo, generalmente tiene un diseño bastante específico que debe funcionar para cualquier resolución y poder mostrar los datos que envíe. Necesita cosas como, por ejemplo, mover algunos botones hacia abajo para dejar espacio para un texto más largo. Con la GUI "retenida", puede tener un control que lo hace automáticamente. Con el modo "inmediato", no hay controles, por lo que debe hacer todo explícitamente.

Otro problema con UnityGUI (no estoy seguro si le ocurre a todas las GUI de modo inmediato) es que, por ejemplo, una Button()llamada funciona sin considerar ninguna otra llamada de GUI. Entonces, si un botón está encima de otro, un clic presionará ambos botones al mismo tiempo. Esto definitivamente no es lo que el usuario espera, por lo que agrega otro caso especial para manejar.

Para vivir con todo esto, siempre he escrito mi propio contenedor alrededor de UnityGUI que lo convierte en un sistema de modo "retenido": controles que almacenan su propio estado y solo llaman a las GUIfunciones requeridas cada cuadro para mí.

No puedo decir que el modo "inmediato" sea definitivamente peor que "retenido", pero ciertamente me siento mucho mejor trabajando en modo "retenido".

No importa
fuente
1
Sí, he experimentado cada uno de estos problemas con la GUI de Unity y, como resultado, lo odio. Es ideal para HUD estáticos rápidos, pero una verdadera molestia para cualquier otra cosa.
Kylotan
7

Voy a defender IMGUI aquí porque algunos de los problemas que se enumeraron anteriormente se pueden resolver si está dispuesto a escribir el código. Además, si escribe el código, entonces tiene una biblioteca robusta que es reutilizable y que rara vez requiere modificación.

  • cargando GUI del esquema

quizás al principio parece que los artistas no tienen mucha flexibilidad con IMGUI, esto se resuelve o mejora al cargar el diseño de la GUI desde un esquema xml o JSON.

  • llamadas de dibujo de capa de menú

este problema se resuelve con la clasificación, debe crear una clase de Administrador de IU que ordene el orden de dibujo, resolví este problema en C # XNA con paneles movibles y que se pueden hacer clic que se dibujan uno encima del otro. Puedo publicar pseudocódigo si me lo piden.

  • cuadros de lista

¿Puedes dibujar cadenas de una matriz? ¿Puedes definir áreas rectangulares a partir del alto y el ancho de las fuentes de esas cadenas? ¿puedes crear una proporción del tamaño de tu botón de desplazamiento por la altura de todos esos rectángulos sumados? Luego está a medio camino de crear un cuadro de lista con un botón desplazable para moverse hacia arriba o hacia abajo. Pensé que iba a ser difícil, pero resultó ser mucho más simple de lo que pensaba. sin buffers, sin estados, sin devoluciones de llamada involucradas.

  • separando datos de la GUI

no permita que los paneles, botones y cuadros individuales contengan los datos. Sé que en mi primer intento de IMGUI fue inmediato pero solo en el sentido gráfico. Cometí el error de retener datos en la interfaz de usuario. Fue casi un cambio filosófico pensar de manera diferente dónde ubicar y modificar los datos a través de los cambios en la interfaz de usuario.

  • GUI de SDK

Este es el límite y la funcionalidad del código del SDK, no el suyo. Encuentro que SDK UI (Hammer, Unity, UDK) es casi un nuevo idioma para aprender de todos modos. De hecho, son similares a mí como Windows. Los formularios, ambos están configurados para la posibilidad más amplia y, por lo tanto, tienen un peso adicional en complejidad.

y finalmente mira esto> http://mollyrocket.com/861

Bixel
fuente
4

Las interfaces de usuario generalmente no necesitan un diseño automático o tener ventanas redimensionables sobre la marcha. En cambio, necesitan interactuar de manera muy eficiente con datos que cambian constantemente (como las posiciones 3D de modelos en el mundo)

Depende del género y juego en cuestión. Un buen sistema de gestión de inventario es vital para la mayoría de los juegos de rol. Va a querer algo que maneje los diseños por usted, soporte de barras de desplazamiento, arrastrar y soltar, información sobre herramientas y otras características mucho más fáciles de implementar usando GUI retenida.

No se me ocurre una forma de arrastrar y soltar con una GUI inmediata que no requiere mucho malabarismo o ahorro de estado del usuario, como cambiar temporalmente el búfer Z y almacenar información de tiempo para descartar un clic que movió un poco.

Pero desde una perspectiva de diseño, tengo problemas para imaginar un mundo sin mis eventos GUI. Además, una GUI Inmediata no es compatible con OOP, lo que le obliga a recurrir a la programación de procedimientos.

La simplicidad que brindan las GUI inmediatas tiene el costo de una complejidad adicional en su código que crece rápidamente a medida que aumenta la complejidad requerida por su UI; donde, como buena GUI retenida, es originalmente más complejo pero se escala mejor. Entonces, por debajo de cierto punto de complejidad, una GUI inmediata es adecuada, pero para la mayoría de las situaciones prefiero una GUI retenida.

Trueno clásico
fuente
1
Quiero preguntarle: ¿Su opinión proviene de la experiencia real del mundo real o del pensamiento teórico al observar ambos sistemas? Uhm ... esto suena más duro de lo previsto, lo siento. Lo que quiero decir es: comparto su opinión y evaluación desde un aspecto teórico . Los sistemas similares a IMGUI probablemente conducen a menos código OOPish (si eso es un problema), tienen problemas con los controles que requieren algún estado, etc. Es solo que ... los sistemas GUI normales también son muy grandes y complejos por sí mismos, por lo que tiene mucha complejidad para agregar hasta que incluso se acerque a estos sistemas ...
Imi
1
Immanuel, no necesitas tener experiencia de desarrollo en el mundo real para saber que muchos juegos necesitan un diseño automático y ventanas redimensionables.
Kylotan
1
@Immanuel Scholz Admito que tengo mucha más experiencia con las IU retenidas; manteniendo uno como un proyecto OSS y haber trabajado con ellos a través de mi operador (que ciertamente es muy joven). Sin embargo, he usado el sistema UI de Unity3D y lo he duplicado cuando me mudé a XNA. Mi IU retenida se desarrolló porque me cansé de copiar y pegar el mismo truco de un proyecto a otro para lograr una funcionalidad uniforme.
ClassicThunder
@Kylotan por "ventanas redimensionables" Me refiero a que puede cambiar el tamaño de los elementos de la interfaz de usuario de forma activa arrastrando (u otros medios) y mediante el diseño automático que cuando los redimensiona, la interfaz de usuario se adapta de una manera "agradable" como mostrar barras de desplazamiento, asignando múltiples líneas para barras de botones, etc. Sí, a veces veo esto en los juegos, pero es mucho más común en las aplicaciones de escritorio. Además, creo que hacer buenas UI redimensionables tampoco es lo más fácil para los sistemas GUI retenidos.
Imi
1
Las ventanas redimensionables y la distribución automática son casi lo mismo. En el modo retenido, las GUI de cada control conocen su tamaño (si cambia en la rutina o no) y la distribución automática es básicamente una verificación de tamaño recursiva. Podría decirse que es más importante en los juegos que en las aplicaciones de escritorio porque esperamos GUI de pantalla completa en una variedad de relaciones de aspecto y en diferentes plataformas.
Kylotan