Непосредственный графический интерфейс - да или нет? [закрыто]


39

Несколько лет назад я работал над разработкой приложений с множеством «сохраненных» систем графического интерфейса (ниже я расскажу о том, что я имею в виду), таких как MFC, QT, Forms, SWING и несколько структур веб-графического интерфейса. Я всегда находил концепции большинства систем с графическим интерфейсом слишком сложными и неуклюжими. Количество событий обратного вызова, слушателей, копий данных, что-то, что можно связать во что-то - преобразования (и т. Д.) Всегда были источником ошибок и головной боли по сравнению с другими частями приложения. (Даже при «правильном» использовании привязок данных / моделей).

Сейчас я пишу компьютерные игры :). До сих пор я работал с одним графическим интерфейсом: Miyagi (не очень известный, но в основном та же идея, что и все другие системы).

Это было ужасно.

В средах рендеринга в реальном времени, таких как Игры, у меня возникает ощущение, что «сохраненные» системы графического интерфейса еще более устарели. Пользовательские интерфейсы обычно не нуждаются в автоматической компоновке или имеют изменяемые размеры окон на лету. Вместо этого им необходимо очень эффективно взаимодействовать с постоянно изменяющимися данными (например, 3D-позициями моделей в мире).

Пару лет назад я наткнулся на «IMGUI», который в основном похож на режим Immediate Graphics, но для пользовательских интерфейсов. Я не уделял слишком много внимания, так как все еще занимался разработкой приложений, а сама сцена IMGUI казалась не слишком широкой и не успешной. Тем не менее подход, который они используют, кажется настолько сексуальным и элегантным, что я захотел написать что-то для следующего проекта, используя этот способ пользовательского интерфейса (я не смог никого убедить на работе: (...)

позвольте мне резюмировать, что я подразумеваю под «удержанным» и «немедленным»:

Сохраненный графический интерфейс: на отдельной фазе инициализации вы создаете «элементы управления графическим интерфейсом», такие как «Метки», «Кнопки», «Текстовые поля» и т. Д., И используете какой-то описательный (или программный) способ размещения их на экране - все до того, как что-либо будет отображено. Элементы управления хранят большую часть своего собственного состояния в памяти, такие как X, Y расположение, размер, границы, дочерние элементы управления, текст метки, изображения и так далее. Вы можете добавить обратные вызовы и слушателей, чтобы получать информацию о событиях и обновлять данные в элементе управления GUI.

Немедленный графический интерфейс: библиотека графического интерфейса состоит из однократных функций «RenderButton», «RenderLabel», «RenderTextBox» ... (редактировать: не запутайтесь в Renderприставка. Эти функции также выполняют логику за элементами управления, такие как опрос пользовательского ввода, вставка символов, обработка скорости повторения символов, когда пользователь удерживает клавишу, и т. Д.), Которую можно вызвать для «немедленной» визуализации элемента управления (не делает). Это должно быть немедленно записано в графический процессор. Обычно его запоминают для текущего кадра и позже сортируют по соответствующим партиям). Библиотека не содержит никакого «состояния» для них. Если вы хотите скрыть кнопку ... просто не вызывайте функцию RenderButton. Все функции RenderXXX, которые взаимодействуют с пользователем, например кнопки или флажки, имеют возвращаемые значения, которые указывают, например, нажал ли пользователь на кнопку. Так что твой "RenderGUI" функция выглядит как большая функция if / else, где вы вызываете или не вызываете функции RenderXXX в зависимости от состояния вашей игры, и вся логика обновления данных (при нажатии кнопки) включается в поток. Все хранилище данных находится «за пределами» графического интерфейса и передается по требованию функциям рендеринга. (Конечно, вы бы разбили большие функции на несколько или использовали бы некоторые абстракции классов для группировки частей графического интерфейса. Мы больше не пишем код, как в 1980 году, не так ли?)

Теперь я обнаружил, что Unity3D фактически использует тот же самый базовый подход к своим встроенным системам графического интерфейса. Возможно, есть пара GUI с таким подходом?

Тем не менее ... при взгляде вокруг, кажется, есть сильный уклон в сторону сохраненных систем графического интерфейса? По крайней мере, я не нашел такого подхода, кроме как в Unity3D, и первоначальное сообщество IMGUI кажется довольно .... тихим.

Так кто-нибудь работал с обеими идеями и имел какое-то твердое мнение?

Редактировать: меня больше всего интересуют мнения, основанные на реальном опыте. Я думаю, что на IMGUI-форуме много горячих дискуссий по поводу любой «теоретической слабости» непосредственного подхода с графическим интерфейсом, но я всегда нахожу более полезным узнать о реальных слабостях.


Проверьте этот вопрос: gamedev.stackexchange.com/questions/3617/good-gui-for-opengl
kaoD

Спасибо за ссылку. Я полагаю, вы имеете в виду комментарий от Kylotan . Интересно ..;)
Imi

1
Ха, я был на полпути к написанию ответа ниже, когда я заметил, что мое мнение уже было замечено ... тем не менее, я все равно опубликую его.
Kylotan

2
Обидно, что эти вопросы закрываются! Это те мнения, которые я ищу, когда у меня такой же вопрос.
Харальд Шейрих

Ответы:


34

Най. Я выполнил оплачиваемую работу gamedev с ужасным графическим интерфейсом «с сохраненным режимом» и с ужасным графическим интерфейсом с «непосредственным режимом», и хотя оба заставили меня захотеть вырвать глаза, подход с сохраненным режимом все еще явно лучше.

Недостатки немедленного режима много:

  • они не облегчают художникам и дизайнерам настройку макета;
  • они заставляют вас смешивать логику с презентацией;
  • они усложняют наличие единой последовательной входной модели;
  • они препятствуют сложному управлению динамическими данными (например, представлениям списка);
  • расслоение становится очень неудобным (например, если я вызываю RenderComboBox, выпадающий список еще не может быть визуализирован, потому что он должен идти над остальной частью окна - то же самое для подсказок) l
  • настройка стиля рендеринга завершается глобальными (ick) или дополнительными аргументами функции (ick);
  • производительность может быть плохой, потому что вызов всех этих функций для запроса значений, которые могли или не могли измениться, имеет тенденцию создавать много маленьких объектов, что подчеркивает работу менеджера памяти;
  • ... и я даже не могу себе представить, как больно было бы позволить кому-то перетаскивать бит GUI и переупорядочивать их. Вам нужно будет поддерживать структуру данных, сообщающую вам, где все визуализировать - это очень похоже на переписывание системы с сохраненным режимом самостоятельно.

Интерфейсы с непосредственным режимом заманчивы для одиноких программистов, которые хотят иметь быструю систему HUD, и для этой цели они хороши. Для всего остального ... просто скажи нет.


1
@ImmanuelScholz: Считаете ли вы, что, возможно, сохраненные графические интерфейсы на самом деле не "такие уродливые"?
Николь Болас

1
Библиотеки GUI, как правило, неэлегонны, потому что они решают несколько проблем - ввод, рендеринг и доступ к данным - и каждая из них находится под сильным влиянием остальной части программы. Это означает, что люди добавляют уровни абстракции, чтобы сделать графический интерфейс многократно используемым в разных программах, устройствах ввода и средствах визуализации, за счет усложнения его использования.
Kylotan

2
Добавьте к этому тот факт, что нет единого мнения даже о том, как сделать GUI с сохраненным режимом (MVC, MVP и MVVM - это 3 популярных подхода), или как выложить его (из данных? Из кода?) Или как прикрепить поведение ввода ( встроенный скрипт, как в случае с веб-интерфейсом (именованные сигналы / слоты, результаты на месте, как в случае IMGUI?), и это отсутствие стандартизации препятствует разработке One True Way для графических интерфейсов.
Kylotan

2
Для настройки макета художником требуется редактор, независимо от того, используете ли вы сохраненный или непосредственный графический интерфейс. Этот пункт полностью недействителен. Смешение логики и представления - это причина, по которой вы используете непосредственный графический интерфейс, это не недостаток, это то, что вы хотите, в отличие от беспорядка, который сохраняет больше графического интерфейса. Вы даже не так много понимаете. Конфигурация не требует глобальных или дополнительных аргументов, если API хорошо спроектирован. Каждый недостаток, который вы упомянули, разрешим в чистом виде. Самое главное, что вы пишете игровой интерфейс, а не Photoshop.
дрета

3
@dreta: моя точка зрения на конфиг художника заключается в том, что есть вещи, которые совершенно непрактично менять через редактор без написания собственного слоя сохраненного режима поверх него (например, что делать при нажатии кнопки или переупорядочение элементы). IMGUI хорошо работает для очень простых и тривиальных визуальных эффектов, не более того.
Kylotan

31

Как человек с пяти-шестилетним опытом работы с IMGUI на рабочем столе, я чувствую себя обязанным защищать его. Все ответы (и сам вопрос) основаны на очень ограниченном определении IMGUI, и кажется, что делается много сомнительных заявлений.

Во многом это происходит из-за предположения, что библиотека IMGUI не может хранить какие-либо данные в тайне. Это совсем не так. Сложная библиотека IMGUI фактически будет хранить столько же данных, сколько эквивалентная библиотека RMGUI. Разница в том, что библиотека IMGUI в основном кэширует результаты, тогда как библиотека RMGUI поддерживает авторитетное состояние. В IMGUI приложение предоставляет функцию, которая принимает текущее состояние модели и создает графический интерфейс для этого состояния. Это авторитетное определение GUI. Библиотека отвечает за то, чтобы экранный графический интерфейс соответствовал результату этой функции. Это не означает, что необходимо полностью оценить эту функцию в каждом кадре и полностью перестроить графический интерфейс. В этом смысл кеширования.

С этим представлением IMGUI вы можете сделать расширенный макет, и производительность вполне приемлема. Вы также можете сохранить фактическое авторитетное состояние, если это облегчает интерфейс. Смысл IMGUI не в том, чтобы приложение сохраняло все. Приложение, вероятно, не хочет хранить положение каждой полосы прокрутки и развернутое / свернутое состояние каждого узла дерева. Суть в том, чтобы иметь возможность процедурно определять содержимое этих узлов дерева и само их существование.

Я хотел бы пройтись и ответить на все критические замечания IMGUI по пунктам, но я действительно не понимаю многие из них. Большинство из них, кажется, основаны на некотором фундаментальном убеждении, что IMGUI является хакерским, а RMGUI хорошо структурирован, что, я полагаю, проистекает из вышеуказанных недоразумений. Нет никакой внутренней причины, по которой библиотеки IMGUI должны иметь проблемы со сложностью или должны быть завалены глобальными переменными или смешивать логику с представлением. Я скажу, что преимущества IMGUI становятся менее важными, чем более управляемым художником является ваш контент, но я не уверен, почему он будет на самом деле хуже для контента, управляемого художником. (Лично я не использую контент, управляемый художником, кроме таблиц стилей для таких вещей, как цвета, размеры шрифтов / границ и т. Д., Но я не понимаю, почему это будет сложнее реализовать, чем для RMGUI.)

На мой взгляд, IMGUI, безусловно, хорошая вещь. Это дает вам гораздо лучшую модель для рассуждений о вашем графическом интерфейсе. Он становится намного более функциональным и реактивным, и вы сводите к минимуму количество изменяемых состояний, о которых вам нужно рассуждать. С другой стороны, реализация сложной библиотеки IMGUI является довольно сложной задачей и, безусловно, более сложной, чем реализация эквивалентной библиотеки RMGUI. Это компромисс между сложностью библиотеки и сложностью приложения. Если вы планируете создавать сложные приложения (или даже множество простых приложений), компромисс очень хорош. Если вы делаете это для одного приложения, и это довольно просто, вы, вероятно, достигнете своей цели быстрее с помощью RMGUI.

В любом случае, удачи!


5
«Нет никакой внутренней причины, по которой библиотеки IMGUI должны иметь проблемы со сложностью или должны быть завалены глобальными переменными или смешивать логику с представлением». Очень сложно понять, как обычно звонят кнопки IMGUI, например. «Если Button (x, y), то Action» нельзя назвать смешивающей логикой с представлением. Если вы не передаете детали рендеринга вызову, вы не можете позиционировать или стилизовать его (за исключением глобального или статического), и если вы не обрабатываете логику кнопки сразу, то это не совсем графический интерфейс непосредственного режима. Не могли бы вы привести пример, чтобы объяснить?
Kylotan

4
Контекст OpenGL является большим источником ошибок из-за количества общего состояния, и все же даже с этим API в течение многих лет был переход в режим сохранения, поскольку немедленный режим не предлагал ни гибкости, ни требуемой производительности.
Kylotan

1
Проблема не в параллелизме, а в том, что он имеет один большой блок состояний, который является общим. Графический интерфейс с сохраненным режимом инкапсулирует соответствующее состояние с помощью элемента управления, к которому он применяется, и такая инкапсуляция обычно считается хорошей по причинам, которые здесь не нужно повторять. Мои конкретные проблемы перечислены в моем ответе выше, и я еще не видел ни одного подхода IMGUI, который не страдает от всех из них.
Kylotan

3
Соответствует ли таблица стилей CSS «одному большому общему блоку состояний»? В любом случае, я не знаю, каков ваш конкретный опыт работы с IMGUI, но если вы заинтересованы в подходах IMGUI, которые не страдают от этих проблем, я бы посоветовал вам прочитать мой ответ выше и прочитать Форум IMGUI по Молли Ракете. Это правда, что нет идеальной готовой библиотеки IMGUI, которую вы можете скачать и начать использовать в считанные минуты, но если вы заинтересованы в ее создании, есть информация и люди, готовые помочь.
Том

1
Таблицы стилей CSS находятся в статическом состоянии; скорее отличается от контекстов OpenGL, которые чрезвычайно динамичны!
Kylotan

12

Библиотека GUI состоит из однократных функций «RenderButton», «RenderLabel», «RenderTextBox» ..., которые можно вызывать для «немедленной» визуализации элемента управления (не нужно сразу записывать в GPU. Обычно его запоминают для текущего кадра и отсортированы в соответствующие партии позже).

Я бы сказал, что это не библиотека GUI. Это просто набор функций рендеринга.

Рендеринг GUI - самая простая часть создания GUI. Возьмите текстовое поле для примера. Я собираюсь предположить самый простой случай: простое однострочное текстовое поле ввода.

RenderTextBoxпросто нарисую текстовое поле. Это сделает простое измерение текста и нарисует глифы на экране. Это будет не

  • Определите, что пользователь щелкнул мышью в элементе управления, и переместите курсор в нужное место в строке.
  • Определите, что пользователь дважды щелкнул мышью в элементе управления, и выделите блок текста.
  • Определите, что пользователь нажал клавишу «Домой», и переместите курсор в начало текста.
  • Определите, что пользователь нажал правильную клавишу, и измените строку соответствующим образом. Если текст был выбран, выбранная часть будет заменена вставленным текстом.

Я могу продолжать, но я думаю, что моя точка зрения ясна. Если вы хотите использовать RenderTextBoxдля рисования текстовое поле, все, что вы получите, это статическое, нефункциональное текстовое поле. Любая актуальная функциональность должна быть реализована вами.

Делать текстовые измерения и рисовать глифы? Это простая часть работы с графическим интерфейсом. GUI расшифровывается как «Графический интерфейс пользователя». Последние два слова, где вы берете ввод от пользователя и что-то делаете с ним, являются трудной частью.

Игроков ожидают разумного управления графическим интерфейсом. В среде ПК (например, мышь и клавиатура), если игроки видят текстовое поле, они ожидают, что оно будет работать как обычное текстовое поле. Они ожидают, что смогут перемещаться в нем с помощью клавиш со стрелками, прыгать вперед и заканчивать домом и удалять, выбирать буквы в нем и т. Д.

Это означает, что вам придется реализовать весь этот код пользовательского интерфейса. Вы должны проверить, какой элемент управления был нажат. Затем вы должны сделать что-то на основе того, какой элемент управления был нажат. Вы должны иметь понятие «активный» элемент управления, который получает ввод с клавиатуры. Различные элементы управления должны по-разному реагировать на различные типы взаимодействия с пользователем.

В основном вам понадобится TextBoxWindow класс.

Допустим, вы реализуете экран настроек игры. Таким образом, у вас есть различные группы параметров: игровой процесс, графика, звук, элементы управления и т. Д. Итак, у вас есть список различных групп в левой части экрана. Каждая группа вызывает набор элементов управления, которыми пользователь может манипулировать. Что происходит, когда пользователь нажимает клавишу Tab?

Ну, это зависит от того, какой контроль активен. Если один из элементов управления группы активен (последний раз был нажат), он переходит к следующей группе. Если вместо этого активен один из элементов управления в группе, он переходит к следующему элементу управления в этой группе. Вот как система предназначена для работы.

Таким образом, не только активный ввод с клавиатуры должен обрабатывать любой необработанный ввод для элемента управления, которому он принадлежит . Либо так, либо элементы управления должны быть в каком-то связанном списке, чтобы он мог перемещаться взад и вперед. Это означает, что в каждом элементе управления должно быть поведение по умолчанию.

Это все больше и больше напоминает сохраненный графический интерфейс, не так ли? Разница лишь в том, что ... ты тот, кто делает тяжелую работу. Использование кого-либо еще GUI должно быть способом сделать меньше работы. Но усилие, которое требуется, чтобы заставить графический интерфейс реагировать, как ожидает пользователь, нетривиально.

Помните: пользовательский интерфейс не для вас, а для ваших пользователей . Это для игрока. Это должно вести себя так, как они ожидают. И если это не так, то вы потерпели неудачу.

Пользовательские интерфейсы обычно не нуждаются в автоматической компоновке или имеют изменяемые размеры окон на лету.

Это ограниченная и ограничивающая мысль.

Я мог бы рассказать о разных играх с разными потребностями пользовательского интерфейса, которые делают некоторые игры. нужно Resizeable окна и так далее. Но есть гораздо большая проблема.

Ваш образ мышления приводит к проблеме «Битвы за космические сражения».

Если вы никогда не играли в эту игру, это дешевая, инди-игра и игра с большим графическим интерфейсом. Фактический игровой процесс полностью выполнен в графическом интерфейсе (это игра типа «настраивай юнитов и наблюдай, как они сражаются»). Проблема?

Графический интерфейс не может быть изменен!

О, это хорошо, если вы используете обычный монитор или у вас нормальное зрение. Но если вы, например, я, управляете смехотворно огромным монитором (настолько большим, что у вас Windows увеличивает размер всего текста, чтобы вы могли его прочитать), это ужасно . Текст микроскопический. Там нет никакого способа изменить размер шрифта.

Конечно, GSB - это игра на основе графического интерфейса, поэтому для них это абсолютно непростительно. Игра с графическим интерфейсом может сойти с рук.

Никогда не думайте, что ваш пользователь смотрит на свою игру именно так, как вы. Делать это глупо.

Наличие системы GUI, которая может масштабировать себя до разрешения пользователя, действительно независимого от разрешения GUI, требует, чтобы макет был частью самой системы GUI. Если вы не собираетесь предоставлять это, то ваш текст будет казаться крошечным на чьем-то гигантском мониторе. Это не очень хорошая вещь.

Поэтому я бы сказал, что ваше мышление на эту тему недальновидно. Тебе это нужно. Вам нужно то, что предоставляют сохраненные графические интерфейсы. О, вам может не понадобиться все, что предоставляет какая-либо конкретная система графического интерфейса. Но вам нужно немного этого.

Базовая работа, которую вы должны выполнить, чтобы получить данные в систему, - это небольшая цена, которую нужно заплатить в дополнение к разумной уверенности в том, что пользователь может правильно взаимодействовать с элементами управления и что он изменит свой размер в соответствии с потребностями игрока.

Возможно, вам удастся обойтись без графического интерфейса в немедленном режиме, если вы не принимаете много пользовательского ввода от игрока. Но это было бы об этом.


5
Пожалуйста, не поймите это неправильно, но позвольте мне еще раз спросить, говорите ли вы на основе реального опыта реального использования подхода с непосредственным графическим интерфейсом в разработке игр (и, как я прочитал ваше мнение: возможно, заменить его на полпути в разработку разочарования;))? Кстати, ваша изображенная функциональность текстового поля может быть (и, например, в UnityGui.TextField) реализована в классе RenderTextBox. Кроме того, ничто в подходе Immediate GUI не запрещает разработчику библиотеки использовать классы для элементов управления GUI, если это подходит. Просто использование будет принципиально другим.
Ими

1
@Immanuel: «Между прочим: ваша функциональность текстового поля с изображением может быть (и, например, в UnityGui.TextField) реализована в классе RenderTextBox». Вы сказали, что это RenderTextBoxбыла функция , а не класс. Таким образом, ваше разделение между «немедленным режимом» и «сохраненным режимом», по-видимому, заключается в том, где хранятся данные, а не в том, кто ими управляет. Если это так, вам нужно сделать это различие более ясным в вашем вопросе, потому что это предполагает, что «графический интерфейс в непосредственном режиме» просто рисует вещи на экране. Что он не может получить вход (потому что это потребует постоянного состояния) и тому подобное. Так что это?
Николь Болас

1
@ImmanuelScholz: «Я не вижу аргумента против общего« немедленного подхода с использованием графического интерфейса »в этом». Я думал, что объяснил это довольно хорошо: кто-то должен написать код . Кто-то должен получить ввод, переместить курсор, управлять текущим элементом управления, обработать макет и т. Д. Ваше описание «GUI немедленного режима» теряет все это, и все это важно для чего угодно, кроме самого упрощенного вывода на основе GUI. Поэтому я не вижу твоего аргумента, что у «немедленного подхода с графическим интерфейсом» есть какие-то положительные стороны .
Николь Болас

1
Извини, я виноват. «... реализовано в функции RenderTextBox» (не класс). Это является функцией и делает процесс ввода данных пользователем и библиотека делать держать некоторое состояние (например , текущего сфокусированного управления). Пожалуйста, не обижайтесь, но могу ли я предположить, что вы знаете только «немедленный GUI» из моей публикации здесь и не изучали ни IMGUI, ни Unity3D gui? Я, конечно, не понял, что здесь подробно описывает «непосредственный графический интерфейс», я просто хотел бы подвести итог, чтобы мы не говорили о совершенно разных вещах (например, чтобы не путать с «непосредственным графическим режимом»).
Imi

2
@ImmanuelScholz: «Я, конечно, не понял, что подробно описывает« немедленный графический интерфейс »здесь». Тогда ваш вопрос неполон. На самом деле, это вводит в заблуждение, потому что «немедленный режим» подразумевает отсутствие государства. Термин «удерживается» происходит от того факта, что он имеет состояние. Так что, если «графический режим непосредственного режима» сохраняет состояние ... это не немедленный режим.
Николь Болас

8

Некоторое время назад IMGUI также заинтересовали меня, в качестве теста я написал несколько учебных пособий, чтобы ознакомиться с методами (начните здесь, если вам интересно, но это не намного больше, чем C # / XNA + оригинальный «учебник» здесь ) ,

Мне очень понравились IMGUI на короткое время, потому что информация, которую они отображают, всегда актуальна и верна (так как нет состояния, которое вы всегда передаете фактическим данным). Но, в конце концов, я потерял интерес, поэтому теперь я снова использую сохраненные графические интерфейсы.

В конце я подумал, что непосредственность GUI усложнила отделение GUI от данных, и время от времени я пытался отделить вещи, вводя некоторые состояния, нарушая элегантность IMGUI. Я также не думаю, что написание кода для сохраненных графических интерфейсов - это больше работы, чем написание кода для IMGUI, и мне нравится, что сохраненные графические интерфейсы можно запускать и забывать, и мне действительно нравятся события :).

Тем не менее, каждый раз, когда кто-то упоминает IMGUI, что-то внутри меня хочет попробовать еще раз, и стараться изо всех сил сделать это правильно, потому что там действительно есть некоторая элегантность, я просто не уверен на 100%, всегда ли это облегчит вашу работу. Я бы сказал, попробуй, может, попробуй, как я, и напишу несколько уроков (я считаю, что лучший способ освоить новые техники - это объяснить их другим).


8

Я много работал с системой Unity3D GUI, которая работает так же, как вы описали. И я должен сказать, я ненавижу это со страстью.

«Немедленный» подход в некоторых случаях работает действительно хорошо. Во-первых, когда вам нужна только пара кнопок и меток - подумайте, например, о шутере HUD. Создать их с «сохраненным» подходом не очень сложно, но это очень просто с UnityGUI. Второй случай - когда вам нужно набросать много элементов управления на экран, но на самом деле вам нет дела до макета. Особенно, когда точные средства управления известны только во время выполнения. На самом деле это бесполезно в любой игре, но действительно полезно при создании инструментов, работающих в редакторе Unity.

Однако любой полусложный графический интерфейс - например, для (MMO) RPG или стратегической игры - неизбежно превращается в ужасную неразбериху с неразборчивым кодом, полную особых случаев и ломающуюся множеством способов. При создании такого GUI у вас обычно есть довольно специфическая компоновка, которая должна работать для любого разрешения и иметь возможность показывать любые данные, которые вы отправляете на свой путь. Вам нужны такие вещи, как, например, перемещение некоторых кнопок ниже, чтобы освободить место для более длинного текста. С «сохраненным» GUI вы можете иметь элемент управления, который делает это автоматически. В «немедленном» режиме нет никаких элементов управления, поэтому вы должны делать все явно.

Еще одна проблема с UnityGUI (не уверен, что это происходит со всеми графическими интерфейсами непосредственного режима) заключается в том, что, например, Button() вызов работает без учета любых других вызовов GUI. Таким образом, если одна кнопка находится поверх другой, щелчок будет нажимать обе кнопки одновременно. Это определенно не то, что ожидает пользователь, так что это добавляет еще один особый случай для обработки.

Чтобы жить со всем этим, я всегда писал свою собственную обертку вокруг UnityGUI, которая превращает его в систему «сохраненных» режимов: элементы управления, которые хранят свое собственное состояние и просто вызывают необходимые GUIфункции каждый кадр для меня.

Я не могу сказать, что «немедленный» режим определенно хуже, чем «сохраненный», но я определенно чувствую себя намного лучше, работая в «сохраненном» режиме.


1
Да, я испытал каждую из этих проблем с графическим интерфейсом Unity, и в результате ненавижу его. Это отлично подходит для быстрых статических HUD, но реальная проблема для всего остального.
Kylotan

7

Я собираюсь защищать IMGUI здесь, потому что некоторые из проблем, которые были перечислены ранее, могут быть решены, если вы захотите написать код для него. Кроме того, если вы пишете код для него, у вас есть надежная библиотека, которую можно многократно использовать и которую очень редко требуется модифицировать.

  • загрузка графического интерфейса из схемы

Возможно, на первый взгляд кажется, что у художников нет большой гибкости с IMGUI, это решается или улучшается с загрузкой макета GUI из схемы XML или JSON.

  • слой меню рисовать вызовы

эта проблема решается с помощью сортировки, вы должны создать класс UI Manager, который сортирует порядок отрисовки. Я решил эту проблему в C # XNA с помощью подвижных панелей с возможностью нажатия, которые рисуются друг на друге. Я могу опубликовать псевдокод, если спросят.

  • списки

вы можете рисовать строки из массива? Вы можете определить прямоугольные области от высоты и ширины шрифтов этих строк? Вы можете создать отношение размера кнопки прокрутки к высоте всех этих прямоугольников, добавленных вместе? Затем вы на полпути к созданию списка с прокручиваемой кнопкой для перемещения вверх или вниз. Я думал, что это будет трудно, но все оказалось намного проще, чем я думал. без буфера, без состояний, без обратных вызовов.

  • отделение данных от GUI

не позволяйте отдельным панелям, кнопкам, полям хранить данные. Я знаю, что моя первая попытка IMGUI была немедленной, но только в графическом смысле. Я сделал ошибку, сохранив данные в пользовательском интерфейсе. Это был почти философский сдвиг, чтобы по-другому думать о том, где размещать и изменять данные через изменения пользовательского интерфейса.

  • GUI из SDK

это предел и функциональность кода SDK, а не ваш. Я считаю, что SDK UI (Hammer, Unity, UDK) - это почти новый язык для изучения в любом случае. На самом деле они похожи на меня как Windows. Формы, обе настроены на максимально широкую возможность и поэтому имеют некоторый дополнительный вес по сложности.

и, наконец, посмотреть это> http://mollyrocket.com/861


4

Пользовательские интерфейсы обычно не нуждаются в автоматической компоновке или имеют изменяемые размеры окон на лету. Вместо этого им необходимо очень эффективно взаимодействовать с постоянно изменяющимися данными (например, 3D-позициями моделей в мире).

Это зависит от жанра и игры. Хорошая система управления запасами жизненно важна для большинства любой RPG. Вам нужно что-то, что обрабатывает макеты для вас, поддерживает полосы прокрутки, drag-n-drop, всплывающие подсказки и другие функции, которые намного проще реализовать с помощью Retained GUI.

Я не могу придумать способ перетаскивания n-drop с немедленным графическим интерфейсом, который не требует много манипуляций или сохранения состояния пользователя, таких как временное изменение буфера Z и сохранение информации о времени, чтобы исключить щелчок, который произошел для перемещения немного.

Но с точки зрения дизайна мне сложно представить мир без событий с графическим интерфейсом. Также графический интерфейс Immediate не совместим с ООП, заставляя вас прибегать к процедурному программированию.

Простота, предоставляемая непосредственными графическими интерфейсами, достигается за счет дополнительной сложности в вашем коде, которая быстро растет по мере увеличения сложности, требуемой вашим пользовательским интерфейсом; где хороший сохраненный графический интерфейс изначально сложнее, но лучше масштабируется. Поэтому ниже определенного уровня сложности немедленный графический интерфейс является адекватным, но для большинства ситуаций я бы предпочел оставить графический интерфейс.


1
Я хочу спросить вас: ваше мнение исходит из реального реального опыта или из теоретической мысли, рассматривающей обе системы? Хм ... это звучит более резко, чем предполагалось, извините ... Я имею в виду следующее: я разделяю ваше мнение и оценку с теоретической точки зрения . Подобные IMGUI системы, скорее всего, приводят к меньшему количеству кода OOPish (если это вызывает озабоченность), у них есть проблемы с элементами управления, которые требуют определенного состояния, и так далее. Это просто ... нормальные системы с графическим интерфейсом также сами по себе очень большие и сложные, поэтому вам придется добавить много сложностей, пока вы не приблизитесь к этим системам ...
Imi

1
Иммануил, вам не нужно иметь опыт реальной разработки, чтобы знать, что многим играм требуется автоматическое расположение и изменяемые размеры окон.
Kylotan

1
@ Иммануил Шольц Я признаю, что у меня гораздо больше опыта работы с оставшимися пользовательскими интерфейсами; поддержание одного из проектов OSS и работа с ними через моего оператора (который, по общему признанию, очень молод). Однако я использовал систему пользовательского интерфейса Unity3D и продублировал ее, когда перешел на XNA. Мой сохраненный пользовательский интерфейс был разработан, потому что я устал от копирования и вставки одного и того же хака из проекта в проект для достижения единой функциональности.
ClassicThunder

@Kylotan - «изменяемые размеры окон». Я имею в виду, что вы можете активно изменять размеры элементов пользовательского интерфейса, перетаскивая (или другими способами) и автоматически компоновая, что при изменении их размера пользовательский интерфейс адаптируется «хорошим» способом, таким как отображение полос прокрутки, выделение нескольких линии для кнопок и так далее. Да, иногда я вижу это в играх, но это гораздо чаще встречается в настольных приложениях. Кроме того, я думаю, что создание хороших изменяемых размеров пользовательского интерфейса не самая простая вещь для сохраненных систем с графическим интерфейсом.
Ими

1
Изменяемые размеры окон и автоматическое расположение - это одно и то же. В графическом интерфейсе с сохранением режима каждый элемент управления знает свой размер (независимо от того, изменяется ли он при рутинном изменении или нет), и автоматическое расположение является в основном рекурсивной проверкой размера. Возможно, это важнее в играх, чем в настольных приложениях, потому что мы ожидаем полноэкранный графический интерфейс в различных пропорциях и на разных платформах.
Kylotan
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.