Как настроить смартфоны и ПК. Информационный портал
  • Главная
  • Железо
  • Unreal против Unity: на чем лучше разрабатывать мобильные игры? Результаты эталонного тестирования. Кадровая частота

Unreal против Unity: на чем лучше разрабатывать мобильные игры? Результаты эталонного тестирования. Кадровая частота

На прошлых уроках мы смоделировали и затекстурировали ландшафт, здания и предметы экстерьера. Как теперь объединить все эти объекты в одной сцене и расставить их в нужные места? Где найти недостающие объекты - машины, деревья, кусты, цветы? Об этом мы узнаем на данном уроке.

В этом уроке мы будем вставлять объекты в сцену с помощью команды Merge (Объединить), а расставлять эти объекты контроллерами Position List (Контроллер положения по списку), Path Constraint (Ограничение по пути), инструментом Snapshot (Тип объекта), плагином MultiScatter и его модулем MultiPainter , а также научимся переводить объекты в Proxy-объекты .

1. Вставка объектов из других файлов.

1. Откроем файл с ландшафтом. Именно в этот файл мы будем вставлять все остальные объекты и расставлять их по нарисованному ландшафту.

2. Вставим здания. Для этого зайдем в меню File (Файл) > нажмем на стрелочку рядом с кнопкой Import (Импорт) > Merge (Объединить) (Рис. 1).

Рис. 1. Применение команды Merge

3. В открывшемся окне необходимо выбрать нужный файл и нажать Open (Открыть) (Рис. 2).


Рис. 2. Выбор нужного файла

4. Появилось окно Merge (Объединить), в котором перечислены названия всех объектов из присоединяемого файла. Нам нужны только здания. Чтобы выделить только необходимые нам объекты, кликаем по ним с зажатой клавишей Ctrl . Нажимаем ОК (Рис. 3).


Рис. 3. Выбор необходимых объектов

Выбранные объекты вставились в сцену с ландшафтом (Рис. 4).


Рис. 4. Вставка объектов

Задание 1

Самостоятельно вставьте в этот же файл все предметы экстерьера (Рис. 5).


Рис. 5. Вставка предметов экстерьера

Примечание: если Вы располагали все объекты на своих слоях, то при вставке этих объектов в другой файл, слои также скопируются. Поэтому, если Вы добросовестно создавали слои как описано в уроках, то сейчас у Вас в Manage Layers (Менеджер слоев) должны присутствовать слои как на Рис. 6.


Рис. 6. Вид менеджера слоев

2. Вставка объектов из библиотек готовых моделей

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

Есть множество сайтов, откуда можно скачать подобные модели, например:

  • http://www.3dklad.com/ и т. д.

Также, некоторые готовые модели можно скачать из раздела «Библиотека» на этом сайте.

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

    Во-первых, при поиске моделей следите за тем, чтобы материалы модели соответствовали тому визуализатору, в котором вы работаете (VRay).

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

Только после этого можно смело вставлять модель в свою сцену без опасения ее перегрузки.

Задание 2

Скачайте, проверьте и вставьте (Import > Merge ) в нашу сцену модели деревьев, кустов, цветов, камней, машин и далее на свое усмотрение (Рис. 7).


Рис. 7. Вставка готовых моделей

Обязательно создайте слои для этих объектов и разместите их каждый на своем слое (Рис. 8).


Рис. 8. Вид менеджера слоев

3. "Ручная" расстановка объектов

Для более точной и тонкой настройки сцены очень удобно пользоваться ручным способом расстановки объектов. Поэтому здания, скамейки, урны, дорожные знаки, цветы и камни для клумб, машины мы будем расставлять самым обычным образом - "вручную", просто перетаскивая их мышкой с помощью инструмента Select and Move (Выделить и переместить). Недостающие объекты получим с помощью копирования с зажатой клавишей Shift . Тип копирования выберем Instance (Образец) (Рис. 9).


Рис. 9. Копирование недостающих объектов

В итоге мы должны получить сцену как на Рис. 10, Рис. 11.


Рис. 10. Вид сцены после "ручной" расстановки объектов


Рис. 11. Расставленные объекты

4. "Автоматическая" расстановка объектов с помощью контроллеров, перевода в Proxy и инструмента Snapshot

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

1. Выделяем объект, например, фонарь.

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

Сформулируем обязательные условия для перевода объекта в Proxy-объект .

    Если объект состоит из нескольких составных частей, то их необходимо объединить с помощью команды Attach в один объект.

    На объект уже должны быть наложены все текстуры.

Только после выполнения этих условий, объект можно переводить в Proxy . Для этого щелкнем по объекту правой кнопкой мыши и в открывшемся контекстном меню выберем команду V-Ray mesh export (Экспорт в поверхность V-Ray) (Рис. 12).


Рис. 12. Перевод объекта в Proxy

В открывшемся окне в поле Folder (Папка) укажите путь для сохранения Proxy-объекта (желательно создать папку для Proxy-объектов в папке проекта, чтобы при работе над своим проектом на другом компьютере Proxy-объекты не потерялись). В поле File (Файл) задайте имя для Proxy-объекта или оставьте его по умолчанию. Обязательно установите флажок Automatically create proxies (Автоматически создавать Proxy) и нажмите OK (Рис. 13).


Рис. 13. Параметры перевода объекта в прокси

Объект изменит свой внешний вид. Это еще одна особенность Proxy-объектов для облегчения нагрузки. Объект может выглядеть как параллелепипед, как неясная сетка, или вообще как точка и т. д. - в зависимости от выбранных параметров просмотра в параметрах Proxy-объекта - но после визуализации он примет свой настоящий вид (Рис. 14).


Рис. 14. Упрощенные отображения объекта и его визуализация

3. Проверьте, находится ли у Вас Pivot Point (Опорная точка, точка поворота и масштабирования объекта) в основании объекта. Сейчас по умолчанию точка находится посередине фонаря. Её необходимо переместить в его основание. Для этого зайдем во вкладку Hierarhy (Иерархия) и выберем Affect Pivot Only (Влияние на опорную точку). Теперь с помощью Select and Move (Выбрать и переместить) и привязки 3 мы можем передвинуть опорную точку (Рис. 15). После этого не забудем выйти из режима редактирования.


Рис. 15. Перемещение Pivot Point

4. Заранее создадим путь, по которому фонари будут равномерно размещаться. В нашем случае просто создадим Circle вокруг парка, как на Рис. 16.


Рис. 16. Создание пути

5. Назначим фонарю контроллеры . Это понятие относится к анимации в 3Ds Max. С помощью контроллеров разработчик трехмерной графики может гибко управлять изменением анимированного параметра объектов. Контроллеры анимации представляют собой заготовки зависимостей, согласно которым могут изменяться параметры. В этом уроке мы будем использовать контроллеры не для анимации, а для расстановки объектов.

Выделим фонарь и перейдем во вкладку Motion (Движение). Откроем свиток Assign Controller (Назначить контроллер), выделим на строку Position: Position XYZ (Положение: положение по XYZ) и нажмем на кнопку назначения контроллера. Из открывшегося списка выберем Position List (Контроллер положения по списку). Этот контроллер позволяет объединять сразу несколько самостоятельных контроллеров для создания общей анимации, это нам и пригодится в дальнейшем.


Рис. 17. Назначение контроллера Position List

После применения этого контроллера в списках Position: Position List > Position XYZ: Position XYZ появится строка Available (Доступный), позволяющая добавлять к списку новые контроллеры. Выделим эту строку и вновь нажмем на кнопку Assign Controller . В открывшемся диалоговом окне на этот раз выберем Path Constraint (Ограничение по пути). Этот контроллер ограничивает движение объекта по пути, которым является указанный сплайн. Данный контроллер применяется для анимации объектов по сложным траекториям (например, движение автомобиля по дороге). Нажмем ОК (Рис. 18).


Рис. 18. Назначение контроллера Path Constraint

Теперь уже ниже, в свитке Position List выделим Path Constraint и нажмем на кнопку Set Active (Сделать активным). В свитке Path Parameters (Параметры пути) нажмем на кнопку Add Path (Назначить путь) и выберем заранее созданный путь. Обязательно поставим галочку возле Follow (Следовать), выберем нужную ось, если надо отразим с помощью Flip (Отразить). Фонарь переместится в начало пути (Рис. 19).


Рис. 19. Назначение пути

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

Из главного меню Tools (Инструменты) выберем инструмент Snapshot (Тип объекта) (Рис. 20). Он предназначен для создания массива объектов по траектории анимации объекта-оригинала (в нашем случае - анимации фонаря по пути).


Рис. 20. Расположение инструмента Snapshot

В открывшемся окне ставим флажок напротив Range (По траектории), оставляем значения от 0 до 100, Copies (Количество копий) ставим на свое усмотрение. Метод копирования выбираем Instance (Образец) и нажимаем ОК . Мы сразу увидим, как фонари автоматически расставились по нарисованной нами траектории (Рис. 21).


Рис. 21. Применение инструмента Snapshot

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

Если какой-то фонарь встал не на том месте, вы всегда можете его подвинуть "вручную". В итоге у нас получится сцена примерно как на Рис. 22.


Рис. 22. Итоговый вид после расстановки фонарей

7. Расставьте фонари по всему оставшемуся городу. Там, где не очень удобно использовать "автоматическую" расстановку фонарей - сделайте это вручную (Рис. 23).


Рис. 23. Расставленные фонари

Задание 3

Самостоятельно расставьте точно таким же методом маленькие решетки вокруг парка (Рис.).

1. Выделите маленькую решетку и переведите её в Proxy-объект .

2. Передвиньте Pivot Point в основание объекта (Рис. 24).


Рис. 24. Pivot Point в основании объекта

3. Нарисуйте путь для расстановки решетки - Circle чуть больше прежнего.

4. Последовательно назначьте контроллеры Position List и Path Constraint . Сделайте активным контроллер Path Constraint , нажав на кнопку Set Active . Назначьте заранее созданный путь, нажав на кнопку Add Path . Решетка переместилась в начало пути и встала перпендикулярно ему (Рис. 25).


Рис. 25. Решетка расположенная перпендикулярно пути

Это надо исправить, поставив галочку возле Follow (Следовать). Можно выбрать нужную ось, если надо отразить с помощью Flip (Отразить) (Рис. 26).


Рис. 26. Решетка расположенная вдоль следования пути

5. Из главного меню Tools выберем инструмент Snapshot . В открывшемся окне ставим флажок напротив Range (По траектории), оставляем значения от 0 до 100, Copies (Количество копий) ставим на свое усмотрение, главное, чтобы решетки идеально стыковывались друг с другом. Метод копирования выбираем Instance , нажимаем ОК (Рис. 27). Решетки автоматически расставились по нарисованной нами траектории.


Рис. 27. Применение инструмента Snapshot

Удалим изначальную анимированную решетку, нажав клавишу Delete на клавиатуре.

Если какая-то решетка находится не на том месте, например, прямо на дорожке, вы всегда можете подвинуть её "вручную" или совсем удалить. В итоге у нас получится сцена примерно как на Рис. 28.


Рис. 28. Итоговый вид после расстановки маленьких решеток

Задание 4

Самостоятельно расставьте большие решетки вокруг домов и школы. Где-то придется расстанавливать их вручную (например там, где калитки), где-то этот процесс можно автоматизировать. В итоге должно получиться примерно как на Рис. 29, Рис. 30.


Рис. 29. Итоговый вид после расстановки больших решеток


Рис. 30. Итоговый вид после расстановки больших решеток

Задание 5

Расставьте автоматическим методом кусты по нарисованным траекториям (Рис. 31, Рис. 32).


Рис. 31. Расставленные кусты


Рис. 32. Расставленные кусты

5. "Автоматическая" расстановка объектов с помощью плагина MultiScatter - MultiPainter

Мы уже рассмотрели несколько способов расстановки объектов в сцене: "вручную" и "автоматически" по траектории. Но что делать, если нам надо расставить буквально миллионы копий объекта, таких как трава или лес? Уже знакомые нам способы здесь не помогут.

Вы, наверное, уже слышали о MultiScatter . Это плагин для 3Ds max, с помощью которого можно легко и просто создавать сцены с миллионами объектов. Новая версия MultiScatter включает в себя новый и очень полезный модуль MultiPainter . Он позволяет «рисовать» объектами по поверхности, используя виртуальную кисть. Рисование может происходить как по одной поверхности, так и сразу по нескольким. Рисовать можно сразу несколькими разными объектами. Поэтому MultiPainter идеально подходит под наши задачи.

1. Скачайте и установите плагин MultiScatter .2. Выделите пучки травы и переведите их Proxy-объекты (щелкаем правой кнопкой мыши > VRay mesh export) . В открывшемся диалоговом окне задаем имя и папку, ставим галочку Automatically create proxies . Нажимаем ОК .

3. Проверьте, чтобы Pivot Point находился в основании пучков травы.

4. Теперь мы можем расставлять эти объекты с помощью MultiScatter - MultiPainter . Для этого на вкладке Create выбираем Geometry и из выпадающего списка выбираем MultiScatter , нажимаем на кнопку MultiPainter .

После этого обязательно ставим его обозначение прямо в сцену - для этого зажмем левую кнопку мыши и потянем курсор в любую сторону (Рис. 33).


Рис. 33. Обозначение MultiPainter

5. После этого переходим во вкладку Modify . Здесь мы видим параметры только что установленного MultiPainter .

В свитке Paint Objects (Объекты рисования) в разделе Scatter Objects (Объекты для расстановки) необходимо указать объекты, которыми мы будем рисовать. Нажмем на кнопку +чайник и выберем наши объекты в сцене. Кнопка +список позволяет выбирать объекты из списка, а не из сцены. Выбирайте объекты так, как Вам удобнее. Кнопка -чайник отвечает за удаление объектов для рисования.

После того, как Вы укажете объекты для рисования, станут доступны два параметра - Probability (Вероятность, плотность) и Collision Rate (Значение столкновения). Именно их и надо будет настраивать. Пока что поставим для зеленого пучка значение Probability 200, Collision Rate 5 , а для пожелтевшего пучка Probability 10, Collision Rate 5 .

В разделе Brush Options (Параметры кисти) можно регулировать Radius (Радиус), Softness (Мягкость краев) и Intensity (Интенсивность, сила нажатия) кисти. Поставим Radius 100 , Softness 1 , Intensity 80 . Тут же находятся самые главные кнопки Paint (Нарисовать) и Erase (Стереть).

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

В свитке Rotate (Поворот) можно указать, на сколько градусов могут вращаться объекты при рисовании. Поставим по оси Z значение вращения 360 градусов, чтобы пучки травы казались разными и не повторяющимися.

В свитке Scale (Масштабирование) можно указать, на сколько объекты будут отличаться по масштабу между собой. Поставим значение From (От) 90 , To (До) 100 .

В свитке Preview (Предварительный просмотр) можно выбрать режим отображения объектов во вьюпорте. Box - каждый объект будет в виде параллелепипеда, Cross - в виде крестика, Points, Count - в виде набора точек, None - никак не будет отображаться во вьюпорте, что может очень помочь в тяжелой сцене.

Все необходимые настройки представлены на Рис. 34.


Рис. 34. Настройки MultiPainter

6. Итак, мы установили все необходимые нам параметры и настройки. Теперь выделим оба пучка в разделе Scatter Objects и нажмем кнопку Paint (Нарисовать). Рисуем кистью прямо по нашему газону (Рис. 35).


Рис. 35. Рисование кистью

Насколько установленные параметры удачны для сцены, можно увидеть только после предварительной визуализации. Посмотрим на результат, отрендерив картинку (Рис. 36). Если требуется, меняем необходимые параметры.


Рис. 36. Расставленные в сцене пучки травы

Задание 6

Расставьте пучки травы по всему городу, тем же методом расставьте деревья в городе (Рис. 37) и за его пределами (Рис. 38).


Рис. 37. Расставленные в городе трава и деревья


Рис. 38. Расставленные за пределами города трава и деревья

Примечание: чтобы сэкономить ресурсы компьютера, можно расставлять объекты только там, где будет пролетать камера.

Это интересно!

А не так давно нам попалась на глаза интересная статья о разработке мобильных игр с применением Unity (от 12 августа 2015 года); правда, ключевое достоинство статьи заключается в том, что в ней этот инструмент сравнивается с основным конкурентом: Unreal Engine.

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

Статья переведена с небольшими сокращениями

Мы (компания OnlineFussballManager GmbH) в настоящее время приступаем к разработке нового проекта для мобильных устройств. Мы собираемся создать захватывающую и уникальную комбинацию пошаговой стратегии и игры типа «футбольный менеджер».

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

Итак, момент истины настал, когда мы взялись за разработку визуального представления.
Учитывая поставленные перед нами требования и тот факт, что мы должны разработать эту игру и для iOS, и для Android - как реализовать этот проект технически?

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

Конечно, можно привести массу доводов о том, какой движок лучше и для каких целей. Сколько людей - столько мнений. Должны признаться, на какой-то момент и мы ощутили такой субъективизм. Команда активно поддержала Unreal Engine. Однако, сколько мы ни присматривались к UE, никто не мог охарактеризовать его объективно, без апелляции к личному мнению.

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

Далее пришел черед Cocos2D, который на первый взгляд казался многообещающим. Как понятно из названия, Cocos2D оптимизирован под разработку двухмерных игр. Поэтому возникал вопрос: хотим ли мы создать нашу изометрическую сетку зданий в истинном 2D или в фактическом 3D с фиксированной точкой обзора. После некоторых дополнительных исследований мы выбрали реализацию в 3D. В таком случае Cocos2D нас, очевидно, не устраивал.

Мы обратились к Marmalade. Ведь при помощи Marmalade были созданы такие известные игры как »Plants vs. Zombies« и »Godus«. Но, хотя мы и нашли у этого движка немало достоинств, оставались проблемы, вынудившие нас обратиться к другим вариантам. Один из наиболее существенных недостатков заключался в том, что сообщество специалистов по Marmalade довольно невелико.

Итак, из крупных альтернатив остались только Unreal и Unity. Но даже к этому моменту мы не могли уверенно выбрать один из двух без посторонней помощи.

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

Встретились там с ребятами из Epic, вплотную познакомились с Unreal Engine, попробовали Paper 2D, их инструмент для просмотра превью мобильных приложений и спросили, чем бы нам воспользоваться: их движком или Unity?

Ребята нам удружили, сказав примерно следующее: «Unreal классный, но и Unity неплох. Попробуйте и то, и другое».

Тогда мы отправились к разработчикам Unity и присмотрелись к Unity 5 - как он повышает производительность в iOS. В конце концов, задали им такой же вопрос и получили аналогичный ответ.

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

Поскольку все наши программисты были заняты на текущих проектах, мы поручили работу над прототипом специалистам из компании Bit Baron.

Исследование движков, выполненное в компании Bit Baron

Компания »Online Fußball Manager« (OFM) планировала создать мобильную игру. Нас попросили о помощи, чтобы увереннее определиться, какой движок лучше всего подходит для их проекта. До тех пор мы занимались исключительно разработкой браузерных игр, но решили, что справимся с задачей. Было предложено сравнить два варианта: Unity и Unreal. В настоящее время это два «локомотива» в мире программирования игр. Существует немало отчетов, подробно иллюстрирующих мельчайшие различия между ними. Но особенность нашей работы заключалась в том, что мы написали для сравнения два практически идентичных тестовых приложения и охарактеризовали их показатели в соответствии с системой контрольных точек (эталонное тестирование).

Написав два аналогичных приложения, мы смогли протестировать оба на ровном игровом поле, сообщить OFM, какая версия работает лучше и подчеркнуть дополнительные проблемы.

Тестовый кейс

Мы хотели создать такой эталонный тест, который бы предоставил OFM информацию, непосредственно связанную с типом создаваемой ими игры. Заказчики указали, что в прототипе должно быть несколько анимированных зданий и деревьев. Поэтому мы создали 3D-сцену, где пользователю предлагалось самостоятельно расставлять эти объекты на карте. Размеры сетки составляли 11x16, она вмещала до 176 зданий. Каждый квадрат сетки поддерживал до 6 деревьев, таким образом, в сцене могло быть свыше 1000 деревьев. Мы добавили простой пользовательский интерфейс, где можно было добавить в сцену указанное количество деревьев и зданий. Также добавили функцию добавления зданий в конкретных местах - для этого нужно было щелкнуть по карте в желаемой точке. Что касается организации программы, мы построили сетку на плоскости, а просмотр сцены сделали через камеру, расположенную «над головой» пользователя. Мы также добавили специальный функционал камеры, чтобы пользователь мог масштабировать и панорамировать сцену. Поскольку этот прототип создавался, чтобы определиться с движком для разработки, мы сделали все возможное, чтобы в обоих вариантах сцена выглядела почти одинаково. В противном случае было бы невозможно сравнить визуальное качество первого и второго варианта. Для этого пришлось повозиться, поскольку некоторые вещи обрабатываются в Unreal и в Unity по-разному. В итоге у нас получились две очень похожие сцены.

Чтобы унифицировать тестирование производительности, мы хотели применить в обеих системах идентичные модели деревьев и зданий. Для деревьев использовалась мобильная модель SpeedTree, включавшая как раз около 1000 многоугольников и позволяла хорошо оценить, насколько мелкие инкременты в отображаемых треугольниках сказываются на кадровой частоте. Что касается анимированных зданий, нам не удалось найти для них такую модель, которая работала бы с обоими движками, поэтому мы применили две разные модели. Обе были рассчитаны чуть более чем на 16 000 многоугольников каждая, у них были практически идентичные настройки материалов. Мы полностью отключили уровни детализации (LOD), чтобы в обоих вариантах на любом расстоянии от камеры отображалось одинаковое количество треугольников. Тест проектировался не только с целью отразить различия производительности между двумя движками, но и чтобы показать разницу в качестве рендеринга. Кроме того, приходилось внимательно следить за стандартными шейдерами Unreal Engine. Заметив, что Unreal выглядит явственно лучше, мы обнаружили, что в камере действует ряд шейдеров, затратных с точки зрения производительности. После их отключения сцена визуально почти не изменилась. Освещение представляло совсем другую проблему, поэтому нам понадобилось некоторое время, чтобы довести его до ума.

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

Проект Unity

Прототип в Unity. На карте нанесено 200 деревьев

Хорошее

  • Основные элементы Unity – это объекты (»GameObject«) и компоненты (»MonoBehaviour«). Освоив эту концепцию, вы уже можете работать с Unity. Если правильно пользоваться этой системой, она позволяет значительно улучшить организацию проекта.
  • В Unity включено много компонентов, обеспечивающих вас всем необходимым для создания игры – кроме игровой логики как таковой. Как было указано выше, компонент может быть таким маленьким, как Plane (в Unreal отсутствует), который мы использовали для построения сетки. Новейшие дополнения движка - компоненты »UI« и »Layout«, обеспечивающие создание мощных и масштабируемых графических пользовательских интерфейсов.
  • Редактор можно расширять собственными сценариями, кроме того, в Asset Store доступна масса ресурсов на все случаи жизни. Хранилище Asset Store также содержит множество полезных сценариев, моделей материалов и пр. Они будут особенно кстати при прототипировании - можете просто загрузить все необходимое в виде временных ресурсов и пользоваться этим как подручными имитационными моделями.
  • Unity был одним из первых общедоступных движков, поддерживавших мобильную разработку. Поэтому он очень удобен при развертывании в мобильной среде, выглядит и действует там практически так же, как и в редакторе. Система постоянно совершенствуется, и развертывание протекает очень гладко. Это был существенный фактор, благодаря которому мы решили делать мобильный прототип.
  • Пожалуй, Unity может похвастаться самым широким сообществом специалистов среди всех игровых движков, поэтому если у вас возникнет вопрос - скорее всего, ответ на него найдется. Пусть Unity и поддерживает множество языков для написания сценариев, документация по каждому из них очень основательная. Более того, даже если вы найдете ответ, касающийся другого языка, логика этого ответа будет вам, тем не менее, понятна, и вы сможете адаптировать ее для решения своей проблемы.
  • В Unity проделана огромная работа по оптимизации рендеринга для множества однотипных объектов. Чтобы добиться сопоставимой производительности в Unreal, пришлось бы задействовать Instanced Rendering, а этот механизм обычно менее гибок, чем рендеринг в Unity.

Плохое

  • Исходный код движка закрыт. Если вы обсуждать с Unity цену исходного кода, то с этим придется смириться. Поэтому возможны проблемы, если откажет та или иная возможность, на которую вы полагаетесь - придется ждать обновления.
  • Новая система UI вполне хороша. В ней отсутствует специальный редактор, все изменения вносятся прямо в сцене - а сцена-то очень большая. Когда вы открываете сцену и хотите отредактировать UI, вам сначала придется изрядно увеличить масштаб интересующей вас области.

Это картинка из редактора Unity. Нам очень повезло, что мы смогли дополнить его нашими собственными сценариями

Ужасное

  • C новой системой UI в Unity есть две проблемы. При нажатии пальцем по сенсорному экрану вы не сможете определить, был ли нажат конкретный графический элемент. Допустим, пользователь хочет панорамировать экран при помощи слайдера. Но если мы наследовали класс GraphicsRaycaster, то можно открыть любые желаемые данные, которые могут быть сделаны общедоступными. Если заменить GraphicsRaycaster в объекте холста, то можно проверить, был ли нажат элемент UI.
  • Вторая проблема с пользовательским интерфейсом Unity связана с масштабированием под дисплеи различного размера. В принципе, у объекта холста есть опции масштабирования с некоторыми параметрами. Но организовать их предпросмотр было очень сложно, пришлось несколько раз развертывать приложение на устройстве, пока мы не подобрали нормальную конфигурацию.
  • Кроме того, нас очень озадачила статистическая панель Unity. Реализовав внутриигровой счетчик кадровой частоты, мы сравнили его значение с тем, что выводилось на статистической панели редактора Unity. Эти значения отличались. Поискав в Интернете другие варианты реализации, мы нашли ответ: статистическая панель дает оценку того, сколько кадров промотала бы игра, если бы работала автономно, а не в редакторе. Поэтому логика нашего счетчика кадров была совершенно правильной.

Значения кадровой частоты 37 против 32. В статистической панели Unity видим оценочные данные для автономного приложения, которые не совпадают с реальными

Проект Unreal

Вот как проект выглядит в редакторе Unreal. Здесь есть много специализированных вложенных редакторов, некоторые из которых сравнимы по функционалу с целыми программами

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

Когда настройки были откорректированы, деревья получились лучше, но все равно не так хорошо, как в Unity

Хорошее

  • Пробная версия Unreal совершенно бесплатная. В ней вы получаете полнофункциональный редактор. В Unity также есть бесплатная версия, но переход на Pro обойдется в кругленькую сумму.
  • В Unreal есть мощный редактор, заключающий в себе несколько узкоспециальных редакторов. Если вы знакомы с этими «вложенными» редакторами, то они очень помогут вам в разработке, а зачастую предоставят и такую информацию, которой в Unity вы не увидите. Есть редакторы, которые даже могут послужить полноценной заменой некоторым программам. Взаимодействие всех этих подсистем - просто шедевр.
  • Движок поставляется вместе со всем исходным кодом. Поэтому в нем можно покопаться и понять, как функционируют отдельные детали. Более того, вы даже можете исправлять баги в движке или самостоятельно дополнять его функционал.
  • Визуализация в редакторе великолепна. Просто глаза разбегаются от изобилия опций рендеринга (связанных, например, с освещением или со сложностью шейдеров). Здесь вы найдете массу ультрасовременных шейдеров, которые также поставляются вместе с движком. В принципе, Unreal предлагает наилучший механизм рендеринга на рынке. Можно создавать удивительно красивые сцены.
  • Чертежи (blueprints) удобны для того, чтобы быстро создать что-нибудь простое и реализовать базовую игровую логику. Они превосходно интегрируются с C++, и такое решение принято неслучайно: оно не только открывает широчайшие возможности как для начинающих, так и для опытных разработчиков, но и позволяет им взаимодействовать друг с другом.
  • Общая интеграция с C++ великолепна. Как и горячая перезагрузка.

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

Плохое

  • При разработке на Unreal Engine сложно набрать темп. Даже если вы отлично знаете C++, потребуется немало времени для изучения различных макросов и функций UE4. Это может быть очень сложно для тех, кто одновременно занимается изучением C++.
  • В чертежах можно очень быстро запутаться. Когда логика включает десятки узлов, в каждом из которых находится чертеж, то ее иногда удается упростить до пары строк кода, написанных на обычном C++. Обычно это не проблема, поскольку вполне можно работать и с C++, но с некоторыми вещами, например, »UMG« (система UI) использовать чертежи необходимо, поэтому и возможна путаница.
  • Мобильный симулятор оказался очень непоследовательным. Он выдавал предупреждения, когда мы пытались использовать шейдерные функции, не используемые в мобильной среде, но даже если шейдер проходил валидацию, то мог не сработать. В принципе, этот симулятор – хорошая вещь, но его визуальные качества оставляют желать лучшего.
  • Хотя Unreal и обладает большим сообществом разработчиков, мы редко получали там ответы на вопросы. Кроме того, почти вся оказанная нам поддержка касалась чертежей. Unreal Engine 4 активно наращивает сообщество, это уже удается неплохо, складывается ощущение, что специалисты стремятся развиваться и помогать. Но сообщество Unity все-таки лучше.

Ужасное

  • Серьезно не хватает документации по C++. Онлайновый справочный материал по классам C++ неудобен. Кроме того, из-за постоянных обновлений многие возможности быстро устаревают. Будьте внимательны, просматривая справочные видеоролики, поскольку там может описываться неактуальная версия движка и функции, которые больше не используются.
  • Работая с GUI, мы использовали инновационную систему »UMG«. Она основана на чертежах и может быть очень полезна. Немного поработав, нам удалось унаследовать класс C++ и немного навести порядок с чертежами. Однако система по-прежнему сырая, в ней недостает некоторых элементов управления, например, кнопок-переключателей. Кроме того, соответствующая документация по C++ практически отсутствует. Редактор несколько раз отваливался, пока мы разрабатывали UI. Неожиданные отказы могут стоить целых часов рабочего времени, они изрядно нервируют. Разработка этой системы продолжается, но пока она далека от совершенства.
  • Мобильная разработка с Unreal медленная. Программа развертывается на устройстве очень долго. В Android возникали некоторые визуальные проблемы - например, там были расплывчатые очертания и неосвещенные деревья. В iOS проблемы были гораздо серьезнее. UE4 поддерживает сборку для устройства с iOS лишь при условии, что ваше приложение состоит только из чертежей. Это вина Apple, но мы проделали весь путь по импорту ключей разработки (можете себе представить), прежде чем столкнулись с этой проблемой. В iOS текстуры деревьев, построенных на основе SpeedTree, не отображались, деревья стояли серые и голые, без листьев. Итак, поддержка мобильной разработки в Unity существенно выигрывает по сравнению с Unreal.

Результаты эталонного тестирования. Кадровая частота

Удивительно, но при тестировании кадровой частоты (FPS) на разных устройствах мы получили очень несхожие результаты. На некоторых устройствах Unity выигрывал при любой конфигурации. В других случаях Unreal обставлял Unity в тех тестах, где было много зданий. В принципе, Unreal выиграл, но дорогой ценой. Качество изображения и согласованность в Unity были существенно лучше. Текстуры Unreal на некоторых устройствах выглядели расплывчато, деревья получались значительно хуже. Разница в качестве была отчасти обусловлена тем, что отображается с одной стороны в редакторе Unreal и мобильном превью, а с другой – на реальном мобильном телефоне. Эта проблема была особенно очевидна, если говорить об освещении сцены. Было очень сложно подобрать настройки так, чтобы правильно настроить свет, весь сеттинг на мобильных устройствах зачастую выглядел затемненно. В этом отношении Unity оказался гораздо последовательнее, изображение на любых смартфонах было таким же, как и при предварительном просмотре в редакторе.

Результаты для обоих движков оказались гораздо лучше, чем мы рассчитывали (как вы помните, в наших тестовых моделях было примерно в 10 раз больше треугольников, чем в обычных мобильных играх).

В iOS оба движка примерно с одинаковым успехом отображали анимированные модели. Однако тесты с деревьями на этом устройстве оказались безрезультатными, поскольку Unreal не отобразил никаких текстур на моделях деревьев. Мы попытались найти причину этой модели, но не смогли ее разрешить. Кроме того, должны отметить, что при развертывании с применением этих движков у вас под рукой должен быть компьютер Apple. Это очень неудобно, но виновата в такой ситуации сама компания Apple. Заказчики также просили нас выполнить эталонное тестирование на Windows Phone. К сожалению, Unreal пока не поддерживает развертывания на Windows phone, поэтому здесь Unity победил по определению. Поскольку пока Windows Phone занимает очень небольшую долю рынка, развитие Unreal в этом направлении не считается приоритетной задачей.

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

Другие контрольные параметры

Вот еще некоторые интересные результаты, которые удалось выяснить в ходе наших тестов:

  • Оба движка почти не отличались по потреблению памяти. На устройствах с Android немного выигрывал Unity, на устройствах с iOS - Unreal.
  • Проект Unity существенно компактнее (Android: 42 MB / iOS: 100 MB) чем Unreal (Android: 101 MB / iOS: 173 MB).
  • Unity примерно втрое быстрее развертывается на устройстве. Кроме того, в Unity гораздо быстрее компилируется код.
  • Unreal значительно экономнее расходовал батарею. Спустя два часа работы со 150 анимированными моделями на экране Unreal успел разрядить батарею Android на 42 процента и iOS – на 36 процентов. Unity потребил примерно 72 процента на Android и 47 процентов на iOS при такой же настройке и длительности работы.

Выводы

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

Несмотря на то, что изначально мы ставили на победу Unreal Engine, в настоящее время Unity все-таки более выигрышный вариант, как минимум, если говорить о разработке мобильных игр.

Вот основные доводы в пользу нашего решения:

  • Unity визуально выглядит более согласованно на всех устройствах, кроме того, быстро развертывается «одним щелчком» на любой платформе.
  • Unity занимает на устройстве гораздо меньше места, меньше сказывается на работе конечного пользователя. Компактный размер особенно важен в Google Play Store, где APK приходится делить на части, если этот файл оказывается крупнее 50mb.
  • Unity гораздо проще изучить и понять. Вооружившись Unity, неопытный пользователь может приступить к работе быстрее и создавать продукты, поддержку которых гарантирует большое сообщество специалистов.
  • Длительность итерации в Unity гораздо меньше (развертывание и компиляция исходного кода происходит быстрее, шейдеры компилируются почти мгновенно)

Мы хотели бы подчеркнуть, что наши результаты следует расценивать в контексте сделанного прототипа. То, что подходит для одной компании, не подходит для другой. Кроме того, существует еще множество игровых движков, некоторые из которых могут лучше соответствовать вашей конкретной задаче. В некоторых компаниях, обладающих достаточным временем и ресурсами, будет целесообразнее даже написать собственный движок. В разработке игр универсального решения не существует. Окажите себе услугу и поэкспериментируйте как следует. Тем более, что многие из них удешевляются или вообще становятся условно бесплатными как Unreal. Мы не удивимся, если Unity также последует примеру Unreal и либерализует ценовую модель.

Заключение

Интересно отметить, что и ребята из Bit Barons до создания прототипа советовали нам взять Unreal Engine для нашего проекта. Учитывая, что и мы в OFM изначально отдавали предпочтение Unreal Engine, возможно, итоговое решение оказалось неоптимальным.

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

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

По кадровому вопросу мы посоветовались с опытными рекрутерами, чтобы узнать более-менее реальные цифры. В данный момент на каждого специалиста по Unreal приходится примерно четыре профессионала по Unity. Что касается бизнес-модели, Unreal не предусматривает первичного фиксированного взноса, а требует лицензионных отчислений. В Unity все ровным счетом наоборот. Оба упомянутых фактора были для нас важны, и в результате мы все-таки остановились на Unity.

Итак, строительство базы в стратегии. Параметры, которые участвуют в этом процессе могут самые разные. Возможно золото или минералы, доступность энергии и прочее. В каждом проекте может быть что-то индивидуальное, однако, общее для всех это само строительство, то есть, расстановка объектов в определенной области. Что нам нужно сделать? Во-первых, у нас есть набор иконок, каждый обозначает некую постройку. При клике по иконке, получаем заготовку постройки, которую можно двигать по плоскости XZ. Во-вторых, нужно сделать так, чтобы новые здания нельзя было создать там где уже есть постройка и там, где запрещено строить что-либо.


Данный вариант подходит только для 3D, для двухмерного проекта надо переделывать рэйкаст и плоскость движения объектов.

Подготовка. Создание самих строений, модельки зданий. Как они будут анимированы и прочее - не важно, главное моделька должны быть под коллайдером, это необходимо не только для строительства, но и для создания карты навигации ботов. Например:

Коллайдер должен закрывать весь объект.

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


Точно также, объект должен закрываться коллайдером, но в режиме Is Trigger . При этом коллайдер макета можно сделать чуть-чуть больше чем у оригинала, на +0.1 допустим, это повысит чувствительность и гарантирует, чтобы невозможно было создать один объект поверх другого. У всех макетов должен быть установлен слой Ignore Raycast! Дополнительно на модельку вешаем Rigidbody и выключаем гравитацию. Плюс, вешаем небольшой скрипт MaskControl :

Using UnityEngine; using System.Collections; public class MaskControl: MonoBehaviour { public string respawnTag = "Respawn"; void Start() { DragAndDrop.isOn = true; } void OnTriggerStay(Collider coll) { if(coll.tag != respawnTag) { DragAndDrop.isOn = false; } } void OnTriggerExit(Collider coll) { if(coll.tag != respawnTag) { DragAndDrop.isOn = true; } } }
Задача этого скрипта в том, чтобы определять где можно установить объект, а где нет. В переменной respawnTag мы указываем тег, который разрешает установку. Допустим если сделать плоскость с тегом, то здание можно строить только в этой области, а если объект наткнется на другие строения то автоматически заблокируется. В общем всё как и обычной стратегии.

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

Теперь вешаем на пустой объект скрипт DragAndDrop :

Using UnityEngine; using System.Collections; using System; public class DragAndDrop: MonoBehaviour { public Transform original; public Transform mask; public float shift = 0.01f; public string respawnTag = "Respawn"; public static bool isOn; private Transform original_tmp; private Transform mask_tmp; private Vector3 curPos; void Start() { isOn = false; } public void SetMask(int id) { foreach(Transform obj in original) { string name = obj.name.Split(new char {"_"}, StringSplitOptions.RemoveEmptyEntries); if(id.ToString() == name) { original_tmp = Instantiate(obj); original_tmp.gameObject.SetActive(false); } } foreach(Transform obj in mask) { string name = obj.name.Split(new char {"_"}, StringSplitOptions.RemoveEmptyEntries); if(id.ToString() == name) { mask_tmp = Instantiate(obj); } } } void Update() { RaycastHit hit; Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out hit)) { curPos = hit.point + hit.normal * shift; } if(mask_tmp) { mask_tmp.position = curPos; if(Input.GetAxis("Mouse ScrollWheel") > 0) { mask_tmp.localEulerAngles += new Vector3(0, 45, 0); } if(Input.GetAxis("Mouse ScrollWheel") < 0) { mask_tmp.localEulerAngles -= new Vector3(0, 45, 0); } if(Input.GetMouseButtonDown(0) && isOn) { original_tmp.gameObject.SetActive(true); original_tmp.position = mask_tmp.position; original_tmp.localEulerAngles = mask_tmp.localEulerAngles; original_tmp = null; isOn = false; Destroy(mask_tmp.gameObject); } else if(Input.GetMouseButtonDown(1)) { Destroy(original_tmp.gameObject); Destroy(mask_tmp.gameObject); } } } }
original - массив всех префабов с оригинальными моделями построек.

mask - массив всех префабов макетов.

shift - сдвиг по оси Y для модельки.

respawnTag - тег плоскости на которой разрешено строительство.

На сцену нужно добавить несколько UI элементов, точнее иконки, GameObject > UI > Image. Создаем нужное количество иконок, размещаем как нужно. Затем, на каждую иконку надо добавить компонент Event Trigger , выбрать в нем функцию Pointer Click а потом перетащить в активное поле объект со скриптом DragAndDrop и меню выбрать функцию скрипта - SetMask и указываем номер макета. Например:


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

ЛКМ по иконке - получить макет здания. Повторный ЛКМ - установить здание. ПКМ - отмена. Колесико мыши - вращать.

Лучшие статьи по теме