image


Привет, Хабр! Меня зовут Александр, и сегодня мы сравним Unity и Unreal Engine 4.


Думаю, многие разработчики пробовали движок Unity и видели сделанные на нём игры, проекты, какие-то демки. Его главный конкурент — движок Unreal Engine. Он берёт своё начало в проектах компании Epic Games, таких как шутер Unreal Tournament. Давайте рассмотрим, как начать работу с движком Unreal после Unity и какие препятствия могут подстерегать нас на пути.


Бывает, что 3D-движки сравнивают весьма поверхностно, либо акцентируют внимание только на одной из фич, например, на графике. Мы же холиварить не будем и рассмотрим оба движка в качестве равноправных инструментов. Наша цель — сопоставить две технологии и помочь вам разобраться в движке Unreal Engine 4. Сравним базовые системы движков на конкретных примерах кода демо-проекта UShooter (Unreal + Unity Shooter), специально сделанного для этих целей. Проект использует версию Unity 5.5.0 и Unreal Engine 4.14.3.


Система компонентов (Unity)


Когда мы запускаем проект на Unreal, то видим, что персонаж в сцене — лишь один объект. В окне World Outliner нет привычных нодов модели (вложенных объектов, мешей), костей скелета и т. д. Это следствие различий систем компонентов Unity и Unreal.


В Unity сцена состоит из объектов типа Game Object. Это пустой универсальный объект, к которому добавляются компоненты, реализованные скриптами поведения (MonoBehaviour) и встроенными компонентами движка. Иногда их оставляют пустыми, в качестве объекта-маркера, на месте которого будет создан, например, игровой персонаж или эффект.


Все эти объекты мы видим в окне Hierarchy в редакторе движка. Они имеют встроенный компонент Transform, с помощью которого мы можем управлять положением объекта в пространстве 3D-сцены. Например, скрипт движения объекта меняет координаты в функции Update, и объект двигается. Для добавления подобного скрипта на Game Object достаточно двух кликов. Создав объект — персонажа или предмет, — мы его настраиваем, добавляем скрипты и сохраняем в prefab (файл, хранящий Game Object и его дочерние объекты). Впоследствии мы можем менять сам prefab, и эти изменения отразятся на всех подобных объектах.


Вот как выглядит класс RocketProjectile, представляющий собой ракету в проекте UShooter.


Фрагмент RocketProjectile.cs
public class RocketProjectile: MonoBehaviour
{
    public float Damage = 10.0f;
    public float FlySpeed = 10.0f;

    void Update()
    {
        gameObject.transform.position += gameObject.transform.forward * FlySpeed * Time.deltaTime;
    }

    void OnCollisionEnter(Collision collision)
    {
        // Обработка столкновения
    }
}

Мы задаём параметры снаряда в редакторе, при желании меняем скорость перемещения (свойство FlySpeed) и урон (Damage). Обработка столкновений происходит в функции OnCollisionEnter. Unity сам её вызывает, так как на объекте есть компонент Rigid Body.


Система компонентов (UE4)


В Unreal Engine 4 игровые объекты представляются Actor’ами и их компонентами. AActor («актер») — это основной класс объекта, который помещается в сцене. Мы можем его создать в игровой сцене (как из редактора, так и кодом), менять его свойства и т. д. Также есть класс, от которого унаследованы все сущности движка: UObject.


image


Компоненты добавляются к Actor’у, игровому объекту. Это может быть оружие, персонаж, что угодно. Но эти компоненты условно скрыты от нас в аналоге Prefab’а — Blueprint Class.


В объекте Actor, в отличие от Unity, существует понятие Root Component. Это корневой компонент объекта, к которому крепятся остальные компоненты. В Unity достаточно мышкой перетащить объект, чтобы поменять у него иерархию вложенности. В Unreal это делается через привязку компонентов друг к другу ("attachment").


В Unity существуют функции Start, Update и LateUpdate для обновления или начала работы скриптов MonoBehaviour. Их аналоги в Unreal — функции BeginPlay и Tick у Actor'а. У компонентов Actor’а (UActorComponent) для этого существуют функции InitializeComponent и ComponentTick, поэтому нельзя «в один клик» сделать из компонента Actor, и наоборот. Также, в отличие от Unity, Transform есть не у всех компонентов, а только у USceneComponent и унаследованных от него.


В Unity мы можем практически в любом месте кода написать GameObject.Instantiate и получим созданный из Prefab’а объект. В Unreal же мы «просим» объект мира (UWorld) создать экземпляр объекта. Создание объекта называется в анриале спауном, от слова spawn. Для этого используется функция World->SpawnActor.


Персонажи и их Controller’ы


В Unreal для персонажей существуют специальные классы APawn и ACharacter, они унаследованы от класса AActor.


APawn — класс персонажа, которым может управлять игрок или AI. В Unreal для управления персонажами есть система контроллеров. Мы создаём Player Controller или AI Controller. Они получают команду управления от игрока или внутреннюю логику, если это AI, и передают команды движения самому классу персонажа, APawn или ACharacter.


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


Описание игрового класса (Actor’а)


Теперь, немного узнав о компонентах Unreal, мы можем взглянуть на класс ракеты в Unreal-версии UShooter.


Фрагмент RocketProjectile.h
UCLASS()
class USHOOTER_API ARocketProjectile : public AActor
{
    GENERATED_BODY()

public: 
    // Sets default values for this actor's properties
    ARocketProjectile();

    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

    // Called every frame
    virtual void Tick( float DeltaSeconds ) override;

    // Rocket fly speed
    UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Rocket")
    float FlySpeed;

    // Rocket damage
    UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Rocket")
    float Damage;

    // Impact (collsion) handling
    UFUNCTION()
    void OnImpact(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);

private:

    /** Collision sphere */
    UPROPERTY(VisibleDefaultsOnly, Category = "Projectile")
    USphereComponent* CollisionComp;
};

Взаимодействие редактора и скриптов, которое в Unity не требует специального кода, работает в Unreal через генерацию кода. Этот специальный код Unreal генерирует при сборке. Чтобы редактор мог показать свойства нашего объекта, мы делаем специальные обёртки: UCLASS, GENERATED_BODY и UPROPERTY. Также мы декорируем свойства и описываем, как редактор должен с ними работать. Например, EditDefaultsOnly означает, что мы можем изменить свойства только дефолтного объекта, blueprint class’а (prefab’а, если провести аналогию с Unity). Свойства могут быть сгруппированы в разные категории. Это позволяет быстрее найти интересующие нас свойства объекта.


Функция OnImpact — аналог OnCollisionEnter в Unity. Но для работы с ней требуется подписаться на события компонента USphereComponent в конструкторе или даже во время игры. Это не работает автоматически, как в Unity, зато здесь есть возможность оптимизации. Если нам больше не нужно реагировать на столкновения, мы можем отписаться от события.


Блупринты (Blueprint)


Типичное действие после создания C++ класса в Unreal — создание на его основе Blueprint Class’а. Это расширение объекта, которое нам предоставляет Unreal. Система Blueprint’ов в Unreal используется для визуального программирования. Мы можем создавать визуальные схемы, соединять события с какими-то реакциями на них. Через блупринты движок упрощает взаимодействие программистов и дизайнеров. Мы можем написать на С++ часть игровой логики и предоставить доступ к ней дизайнерам.


При этом Unreal позволяет отделить, если требуется, C++ исходники проекта от его бинарников и контента. Дизайнеры или аутсорсеры могут работать с собранными dll-библиотеками и никогда не узнают, что происходит внутри C++ части проекта. Это дополнительная степень свободы, предоставляемая движком.


image


Unreal хорош тем, что в нём практически всё связано с Blueprint’ами. Мы можем расширять ими С++ классы, создавать из них Blueprint-наследников и т. д. Эта система тесно связана со всеми компонентами движка, от его внутренней логики до визуальных компонентов, collision, анимации и т. д.


В Unity есть схожие системы визуального программирования, например Antares Universe. Они не входят в состав движка и созданы поверх него, поэтому в любой момент что-то может сломаться (например, при обновлении версии движка). Система визуального скриптования в Unity не предусмотрена. На мой взгляд, это серьёзный недостаток по сравнению с Unreal. Ведь благодаря таким системам даже далекие от программирования люди могут составить схему взаимодействия объектов или связать какую-то последовательность действий. К слову, в Unreal все шаблоны проектов имеют две версии: как на основе C++ кода, так и целиком на Blueprint’ах. Таким образом, создать простой проект без использования кода, целиком на блупринтах — вполне реально.


Демка шутера (UShooter)


В Unity мы пишем демку с нуля, а в Unreal опираемся на шаблоны. В шаблоне выберем управление и вид камеры, и Unreal сгенерирует проект с указанными настройками. Это хорошая основа, от которой вы можете отталкиваться для ускорения разработки и создания прототипа проекта.


image


Поверх шаблона Side Scroller мы добавляем собственный интерфейс (HUD), бочки, несколько видов оружия и звуки. Дадим игроку ракетницу и railgun, пусть героически стреляет по взрывающимся бочкам.


Система ввода (Unity)


Управлять персонажем будем с помощью системы ввода. В Unity мы обычно настраиваем ввод через Input Manager, создаём виртуальные именованные оси. Например, «идти вперёд» или «стрелять». Даём им имена и потом получаем значение какой-либо оси или состояние виртуальной кнопки. Обычно скрипты, которые занимаются управлением объектами, получают состояние осей в функции Update. В каждом кадре опрашивается состояние оси и целого ряда кнопок управления.


Система ввода (UE4)


image


В Unreal тоже есть виртуальные оси, но там есть разделение на собственно оси (значения, полученные от джойстика, и т.п.) и кнопки действия. В отличие от Unity, мы привязываем оси и кнопки к функциям класса, который реализует управление персонажем. Связь создаётся через компонент UInputComponent. Такой компонент ввода есть у класса персонажа ACharacter.


Вызовом BindAxis("MoveRight", this, &AUShooterCharacter::MoveRight) в Input Component мы привязываем нажатие кнопки MoveRight к вызову одноимённой функции движения. Не требуется каждый кадр заниматься опросом кнопки.


Также в Unreal не ограничено количество альтернативных кнопок. В Unity в Input Manager есть только основная кнопка и альтернативная. Чем больше устройств ввода в вашей игре, тем острее может быть эта проблема.


Работа с 3D-моделями


Как уже говорилось, в Unreal мы не видим в сцене структуру скелета персонажа. Дело в том, что компоненты скелета не являются Actor’ами или чем-то подобным. Это внутренние свойства скелета и анимации. Как тогда привязать к персонажу оружие или скрыть одну из его частей? Может, мы хотим надеть на него модную кепку или привязать оружие к руке.


В Unity мы выделим модель оружия в редакторе, перетащим в нужную кость, можем даже повесить на него отдельный скрипт управления. В Unreal мы будем пользоваться сокетами (Socket) — точками крепления на игровых объектах. Сокеты — это часть скелета в моделях со скелетной анимацией (в Unity такие модели называются Skinned Mesh, в Unreal’е — Skeletal Mesh). Также сокеты можно добавлять в статические меши (Static Mesh).


image


Выбираем кость, к которой крепится сокет, и задаём имя сокета, например S_Weapon, если к точке крепится оружие. После создания сокета можно создать («заспаунить») объект в позиции этого сокета или привязать его к сокету через механизм привязки (функции AttachTo). Система немного запутанная, в отличие от Unity, зато более универсальная. Мы можем один раз настроить названия точек, тем самым отделив игровую логику от настроек моделей. Причём если у нас имеется несколько моделей с одним скелетом, то сокеты надо будет добавить только в скелет. В демке шутера сокеты используются при создании снарядов и эффектов выстрела.


Система анимации (Unity)


У нас есть персонаж, мы знаем, как работать с вводом, теперь нужно проигрывать анимацию. В Unity для этого есть Animation Controller, в нём мы описываем определённые состояния персонажа. Например, бежать, прыгать или умереть. Каждому блоку соответствует свой анимационный клип, и мы настраиваем такой граф переходов:


image


Хотя эта схема называется Animation Controller, внутренней логики у неё нет. Это просто схема переключения анимации в зависимости от состояния. Чтобы она работала, мы заранее объявляем в этом контроллере названия переменных, соответствующих состоянию персонажа. Скрипт, управляющий анимацией, зачастую сам передаёт эти состояния контроллеру каждый кадр.


В переходах между состояниями (на схеме показаны стрелочками) мы настраиваем условия переходов. Можно настроить смешивание (crossfade) анимации, т. e. время, в течение которого одна анимация затухнет, а другая продолжится, для их плавного совмещения.


Система анимации (UE4)


В Unreal всё сделано Blueprint’ами, анимация не исключение. Создаём Animation Blueprint, который будет управлять анимацией. Он тоже представляет собой граф состояний. Так выглядит машина состояний, она управляет финальной анимацией персонажа в зависимости от движения или состояния смерти.


image


Тут мы видим уже знакомые нам состояния Idle/Run, Jump, Dead. Но один узел совмещает в себе Idle и Run. Внутри него находится так называемый Blend Space 1D, он используется для плавного перехода анимации в зависимости от значения одной или нескольких переменных. С помощью Blend Space можно привязать скорость персонажа к переходу между анимацией Idle и Run. Кроме того, получится настроить несколько точек перехода. Например, от нуля до метра в секунду персонаж идёт медленно — это будет движение, интерполированное между анимацией Idle и Walk. А после некоторого порогового значения включается бег (Run). И всё это будет в одном узле Animation Blueprint’а, который обращается к Blend State.


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


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


Тут представлено совмещение машины состояний движения с анимацией атаки, которую мы проигрываем через инструмент Montage.


image


В нижней части рисунка — фрагмент схемы Animation Blueprint, который отвечает за реакцию на выстрел из оружия. Команда Montage Play включает анимацию выстрела, затем Delay ждёт, пока она закончится, и анимация выключается командой Montage Stop. Так сделано, потому что в машине состояний анимации мы не можем задать однократное проигрывание анимационного клипа. Если анимация зациклена и соответствует какому-то состоянию персонажа, мы можем управлять анимацией через машину состояний. А если требуется проиграть один клип анимации по событию, то можем сделать через Montage.


Проблема вложенных Prefab’ов


Большая проблема в Unity — вложенные prefab’ы. На случай, если проблема вам не знакома, рассмотрим пример.


Предположим, объект «стол с ноутбуком» сохранили в prefab table1, а затем понадобился второй подобный объект, но уже с зелёным цветом экрана ноутбука. Создаём новый prefab — table2, перетаскиваем в него старый ноутбук, меняем цвет экрана на зелёный, сохраняем. В результате table2, второй prefab, становится совершенно новым объектом, у него нет никаких ссылок на оригинал. Если мы поменяем исходный префаб, это никак не отразится на втором префабе. Простейший случай, но даже он не поддерживается движком.


В Unreal, благодаря наследованию Blueprint’ов, такой проблемы нет: изменение исходного объекта отразится на всех дочерних объектах. Это пригодится не только для игровых объектов, персонажей, какой-то логики или даже статических объектов на сцене, но и для системы интерфейсов.


С другой стороны, можно попытаться победить эту проблему в Unity, используя ассеты в Asset Store. В Unity есть плагины, расширения движка, которые так и называются — Nested Prefabs. Существует несколько подобных систем, но они немного костыльные, сделаны поверх движка, поддержки нет. Они пытаются сохранить в себе внутреннее состояние объекта. Когда запускается игровая сцена, они пробуют восстановить внутренние структуры, их поля, свойства и т. д., удаляют устаревшие объекты в сцене и заменяют их экземплярами из префабов. В результате мы получаем не только удобство вложенных префабов, но и ненужные тормоза, лишнее копирование данных и создание объектов. А если что-то в движке поменяется, то эти системы могут и вовсе отвалиться по неизвестным причинам.


Системы UI


В Unity нельзя сохранить в prefab элементы окон или какие-то виджеты. Можем попытаться, но возникнет та же самая проблема префабов: движок забудет о старых объектах. Поэтому зачастую в Unity мы создаём элементы управления, добавляем скрипты и потом их копируем, не создавая prefab. Если приходится добавлять в такие «виджеты» что-то новое, требуемые изменения нужно повторять вручную.


В Unreal мы можем сохранить элементы интерфейса в виджеты (Widget Blueprint), быстро сделать на основе одних элементов управления новые. Cделали кнопку и надпись, пусть это будет наш status bar widget. На основе стандартных и новых виджетов получается быстро и удобно строить окна интерфейса. К слову, виджеты также расширяются за счет Blueprint’ов, можно описать логику их работы на визуальных схемах.


В Unreal система редактирования интерфейсов и всех виджетов открывается в отдельной вкладке редактора. В Unity интерфейс редактируется через специальный объект Canvas, расположенный прямо в 3D-сцене и зачастую даже мешающий её редактировать.


Преимущества и недостатки


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


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


Из плюсов Unreal стоит отметить визуальное программирование, наследование blueprint’ов, виджеты UI, систему анимации с множеством возможностей и многое другое. Кроме того, в Unreal Engine 4 существует целый набор классов и компонентов, рассчитанных на создание игр: Gameplay Framework. Gameplay Framework является частью движка, на нём созданы все шаблоны проектов. Классы Gameplay Framework открывают множество возможностей — от описания игровых режимов (Game Mode) и состояния игрока (Player State) до сохранения игры (Save Game) и управления персонажами (Player Controller). Особенная фича движка — продвинутая сетевая подсистема, выделенный (dedicated) сервер и возможность запуска сетевой игры в редакторе.


Заключение


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

Поделиться с друзьями
-->

Комментарии (50)


  1. Lailore
    28.04.2017 14:22
    +1

    Кхм, насчет готового код и шаблонов, это помоем намного лучше развито именно у unity.
    Или вы принципиально не рассматриваете то, что сделало комьюнити, а не разработчик?


    1. ASDDeveloper
      28.04.2017 14:34
      +2

      Качество ассетов в unity asset store — очень разное, как и способы реализации и стиль кода. Анриаловские шаблоны рассмотрены в статье, т.к. сразу идут в комплекте движка, имеют встроенные мини-туториалы о их устройстве и единый стиль оформления, плюс построены на базе Gameplay Framework-а и не требуют каких-либо внешних компонентов.


      1. Lailore
        28.04.2017 15:26

        Gameplay Framework — не внешний компонент?


        1. ASDDeveloper
          28.04.2017 15:28

          Он входит в состав движка, его не надо отдельно скачивать или покупать.


          1. Lailore
            28.04.2017 15:30

            У юнити тоже такие встроенные ассеты есть, которые можно установить вместе с движком
            Но плюс ли это? Это же все мусор для прототипирования и новичков


            1. ASDDeveloper
              28.04.2017 15:38

              В юнити пост-эффекты, например, добавляются через импорт package-а. Наверное можно рассматривать как обучающий элемент — новички сразу узнают о механизме импорта ассетов :) Да и простому 2D проекту пост-эффекты могут быть не нужны. Так что наверное не минус и не плюс, а интересная особенность :)


              1. Lailore
                28.04.2017 15:43

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


                1. ASDDeveloper
                  28.04.2017 15:45

                  Можно, но основа для их работы — базовые классы пост эффектов — входят в тот же самый пакет image effects. Поэтому без его импорта придется изобрести систему пост-эффектов заново. Вероятно оно того не стоит.


                  1. eightrichazikon
                    30.04.2017 02:43

                    Вроде как не надо изобретать ничего:) Есть метод который обновляется из бехавиора, если весит на камере, вроде как RenderImage, в параметрах к нему идет кажись буфер изображения, его перекидываете в свой шейдер, и как душе угодно редактируете, и вуаля пост эффект, ничего не нужно изобретать:) И кстати оно стоит того, можно «облегчить» эффект, и контролировать его с учетом нужд архитектуры:) P.S. Но unreal мне нравится больше, от того что исходники разложены по полочкам, что мне по душе, плюс вроде реализован многопоточный рендер, который по отзывам не так выгоден, но это все равно круто:)


                    1. ASDDeveloper
                      30.04.2017 02:47

                      Да, действительно есть такой, OnRenderImage называется. Вероятно имеет смысл его использовать для совсем простых пост-эффектов.


                      1. eightrichazikon
                        30.04.2017 20:34

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


                      1. madMatvej
                        01.05.2017 16:20

                        Почему только для простых?


  1. malan
    28.04.2017 15:02

    В Unreal тоже есть виртуальные оси, но там есть разделение на собственно оси (значения, полученные от джойстика, и т.п.) и кнопки действия. В отличие от Unity, мы привязываем оси и кнопки к функциям класса, который реализует управление персонажем. Связь создаётся через компонент UInputComponent. Такой компонент ввода есть у класса персонажа ACharacter.

    Вызовом BindAxis(«MoveRight», this, &AUShooterCharacter::MoveRight) в Input Component мы привязываем нажатие кнопки MoveRight к вызову одноимённой функции движения. Не требуется каждый кадр заниматься опросом кнопки.

    Также в Unreal не ограничено количество альтернативных кнопок. В Unity в Input Manager есть только основная кнопка и альтернативная. Чем больше устройств ввода в вашей игре, тем острее может быть эта проблема.


    Для Unity можно приобрести плагин Rewired, который ооооооооооооочень значительно расширяет и упрощает работу с контроллерами. За пару часов можно настроить проект для работы с клавой, мышью, десятком геймпадов и под планшет.


  1. malan
    28.04.2017 15:03

    Тут мы видим уже знакомые нам состояния Idle/Run, Jump, Dead. Но один узел совмещает в себе Idle и Run. Внутри него находится так называемый Blend Space 1D, он используется для плавного перехода анимации в зависимости от значения одной или нескольких переменных. С помощью Blend Space можно привязать скорость персонажа к переходу между анимацией Idle и Run. Кроме того, получится настроить несколько точек перехода. Например, от нуля до метра в секунду персонаж идёт медленно — это будет движение, интерполированное между анимацией Idle и Walk. А после некоторого порогового значения включается бег (Run). И всё это будет в одном узле Animation Blueprint’а, который обращается к Blend State.


    Ну в юнити все эти blend tree тоже есть.


  1. DyadichenkoGA
    28.04.2017 15:10

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

    Дело в том, что так как юнити не определяет дубликаты в сцене, то с точки зрения скорости загрузки сцены и т.п. все однотипные объекты лучше инстанцировать при загрузке. Поэтому, по сути, в моём понимании, префаб стола один, а внутри него есть скрипт, берущий префаб ноутбука и создающий необходимый ноутбук, с необходимым цветом экрана. По крайней мере в UI — это точно самая адекватная практика. С 3д, тут соглашусь, если требуется baked освещение и т.п. начинаются пляски с бубном, да и редактировать такое может не очень удобно. Это тожно можно хитро обойти малой кровью, но это уже нужно знать как (да и писать что-то для движка, чтобы с ним было просто удобно работать, звучит странно)

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


    1. ASDDeveloper
      28.04.2017 15:11

      Пример про префабы был образный, чтобы показать суть проблемы.


    1. ASDDeveloper
      28.04.2017 15:15

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


  1. KumoKairo
    28.04.2017 21:04

    Можете немного рассказать про систему, используемую для создания UI? Окошки / анимация / архитектура


    1. ASDDeveloper
      28.04.2017 23:53
      +1

      Обычно создается наследник класса HUD, через который идет взаимодействие механики игры и интерфейса (обмен данными, обработка событий и т.д.). Окошки и прочие элементы интерфейса создаются через Widget Blueprint-ы, которые сочетают в себе визуальную часть UI и блупринтовую логику (переменные, функции и т.д.). На старте (или по событию) наследник HUD-а создает один или несколько основных виджетов и сохраняет ссылки на них у себя в свойствах (Variables). Конкретная схема виджетов и их вложенности/взаимодействия зависит от того каким должен быть интерфейс. Анимации создаются и редактируются прямо в редакторе интерфейса. После создания пустой анимации добавляются участвующие в ней виджеты и их свойства (позиция, цвет и т.д.). Анимации воспроизводятся функцией Play Animation в блупринте этого элемента. Одна анимация может управлять сразу несколькими виджетами. Подробнее лучше смотреть какой-нибудь туториал, например UE4 UMG Animation


  1. alexoron
    28.04.2017 22:57

    Кстати, недавно наткнулся на один очень интересный канал на ютубе — Unreal Engine Rus
    Стримы по созданию игр по разным аспектам.
    Не сочтите за рекламу, если что.


  1. arTk_ev
    28.04.2017 23:01

    Blueprint'ы — это разве плюс движка?
    Визуальное программирование — это не программирование. Это применимо лишь в качестве стейт-машины для анимаций, простых сценарий. В добавок, они еще и бинарные, что мешает использовать git. Для более взрослой логики, эти принты становятся абсолютно нечитаемы, и нельзя применять шаблоны проектирования.

    Хороший движок отличает хорошее api, расширяемость, гибкость, простота и возможность быстро сделать тулзу.
    Unreal, имхо, уже архаичный, как и Photoshop, 3DsMax, с ужасным api и интерфейсом.
    Unity — далек от идеала, но развивается в нужную сторону.

    ps проблем с вложенными префабами в Unity нету — вместо них теперь сцены.
    pps проблема юнити — устаревший рантайм и C#


    1. ASDDeveloper
      28.04.2017 23:13
      +2

      Да, блупринты — весьма себе плюс. Это вам любой дизайнер подтвердит. Визуальный «скриптинг» вполне себя зарекомендовал, и, например, часто используется для описания материалов (шейдеров), причем не только в Unreal. Часть «сложной» логики можно реализовать кодом и сделать доступной для блупринтов, так последние станут менее запутанными и более читаемыми. Про «архаичность» и «тулзы» — анриал все-таки игровой движок, а значит главное его предназначение — создание игр, и с этим он вполне успешно справляется. Что именно показалось вам столь ужасным для меня остается загадкой. А заменять в юнити префабы сценами — как-то слишком странно и костыльно, даже само название намекает что в они предназначены скорее для частей уровня, а не для отдельных объектов.


      1. arTk_ev
        29.04.2017 00:20

        Почти везде для Unity воркфлоу применяется такой:

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


        А вот для Unreal мне не понятен воркфлоу. Кто такие «дизайнеры»? Чем занимаются программисты? Как делаются тулзы для редактора? И почему же отказались от скриптов из UDK в пользу блюпринтов?
        В средней игре миллионы строк кода с постоянным рефакторингом. Я не в состоянии представить весь этот код в виде блюпринтов.


        1. ASDDeveloper
          29.04.2017 01:47

          Не соглашусь насчет того, что в юнити "встроенная компонентная архитектура не применяется", ведь механика добавления компонентов на объекты, их поиск и взаимодействие (даже обращение к встроенному свойству transform или поиск объекта в сцене) — как раз использование этой самой архитектуры. Даже автоматический вызов функций Update, LateUpdate, OnGUI и т.д. тоже является ее частью.


          Теперь к анриалу. В данном ключе "дизайнеры" — те, кто не пишут код, но могут менять/настраивать блупринты. Воркфлоу в анриале такой:


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

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


          1. dimka11
            29.04.2017 10:07

            А такое вообще бывает, что в проекте нет программистов? Написание кода отдается на аутсорс?
            Примерно какого уровня игра?


          1. YoungSkipper
            29.04.2017 22:40

            Не соглашусь насчет того, что в юнити «встроенная компонентная архитектура не применяется», ведь механика добавления компонентов на объекты, их поиск и взаимодействие (даже обращение к встроенному свойству transform или поиск объекта в сцене) — как раз использование этой самой архитектуры. Даже автоматический вызов функций Update, LateUpdate, OnGUI и т.д. тоже является ее частью.


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

            И автоматические вызовы выше перечисленные не используются — ну вернее висит один объект в сцене которые их получает, и уже через собственную компонентную систеум диспатчит в свои компоненты.

            Ибо ответ простой — все что предлагает «встроенная компонентная архитектура в Юнити» можно написать самим и оно будет работать и быстре (сильно быстрее, на порядк) и удобной.


            1. ASDDeveloper
              30.04.2017 02:32

              Да, знакомый подход с кэшированием, но это скорее вопрос оптимизации, и далеко не во всех проектах "обходят" встроенные средства стороной. В юнити частенько приходится многие вещи оптимизировать. Вручную создавать частицы одним эмиттером вместо сотни, "лепить" специальные отражения для воды, дабы каждая лужа сцену не рендерила сама и т.д. Основная фишка юнити — "казуальное", доступное устройство движка, и с ростом масштаба/требований проекта все больше надо воевать за производительность в ущерб "универсальности" и "удобства" :) Хотя, геймдев в целом это искусство фейка и компромиссов, так что нам не привыкать)


            1. Miwwa
              03.05.2017 10:57

              А можете подсказать готовые фреймворки для такого подхода, прошедшие боевое тестирование на реальных проектах? Или каждый разработчик пишет свой велосипед?(


              1. ASDDeveloper
                03.05.2017 10:59

                Готового ничего не встречал, может потому что особо не искал) Тут скорее индивидуальный подход: находим что вызывает проблемы и исправляем :)


        1. orcishhorde
          02.05.2017 19:07
          +1

          Этот подкаст может пролить свет на некоторые из ваших вопросов:
          https://www.youtube.com/watch?v=bzHevRs-cd4

          Тут участвует один из разработчиков UE. Подкаст на русском!


  1. Laguna_Seca
    29.04.2017 01:48

    Меня удивляют люди которые блюпринты считают преимуществом.


    "Ведь благодаря таким системам даже далекие от программирования люди могут составить схему взаимодействия объектов или связать какую-то последовательность действий" — объясните мне, зачем людям далеким от программирования лезть в разработку игр?


    Главное преимущество Unity это C#. Вся его мощь и элегантность доступна в Unity. То что я делаю 2 строчками кода в UE нужно блюпринтить этажами. И вы явно не разбирались в Animator'е Unity и представили как примитивный инструмент. Вы можете смешивать анимации используя слои. К любому состоянию можете написать необходимое поведение.
    В UE ужасная документация и скудный набор стандартных решений. Также не понял про ui и префабы. Любой объект можно сохранить в префабы. Unity к тому же представляет весьма удобный инструмент для создания резинового ui для множества экранов.


    1. ASDDeveloper
      29.04.2017 02:04
      +1

      Проблема префабов — в отсутствии "наследования" объектов, а не в невозможности сохранить в файл. Насчет аниматора согласен, я чаще управлял анимацией старым способом, из кода. Но слои в демке используются. Так что да, имеет место легкая недосказанность :)


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


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


      1. Laguna_Seca
        29.04.2017 03:04

        Что на счет хранения данных в UE?)


        1. ASDDeveloper
          29.04.2017 11:11

          Зависит от данных. Если это настройки или сохраненные игры, можно написать расширение класса SaveGame. Если нужны кастомные свойства на игровых картах — пишем свой класс WorldSettings. Достаточно все поля, требующие сохранения, отметить как UPROPERTY. Для общих данных можно использовать классы DataTable и DataAsset. Для DataTable надо будет сначала описать структуру данных (создать блупринтовую или C++ структуру), а для DataAsset — унаследовать свой класс от него. Кроме встроенного редактора таблиц, в DataTable можно импортировать данные из csv файла. Также можно просто создать структуру и объявить ее как свойство эктора или компонента.


          1. Laguna_Seca
            29.04.2017 13:10

            А в unity подключил sqlite и радуешься.


    1. xdimka
      29.04.2017 13:27
      +3

      Предпочитаю сравнивать достоинства игровых движков по количеству AAA тайтлов выпущенных на нем. Проблема Unity в том, что толковых игр на нем так и не сделали, сомневающиеся могут сравнить список игр на Unity и на Unreal Engine на вики.


      1. Laguna_Seca
        29.04.2017 16:32

        Каждая третья мобильная игра на Unity.


        1. dpolyakov
          30.04.2017 10:08

          99.9% мобильных игр не требуют графику как для РС.


  1. Gosha_say
    29.04.2017 06:18
    -2

    Блюпринт в UE несет огромный минус, это как ютуб в котором все режиссеры, как инстаграм где все супер фотографы. А вот и очередь за программистами. Может и грубо звучит но подобные «упрощалки» влекут за собой появление тонны кривого и однотипного… вна. Сейчас, если сказать, что ты фотограф или дизайнер, так уже и не удивишь, каждый 1.01ый тоже.


    1. dimka11
      29.04.2017 10:12
      +2

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


    1. ASDDeveloper
      29.04.2017 11:26
      +2

      Так можно и про юнити с ассет стором сказать. Купил ассет, поменял название, запостил в стим! Человеческий фактор, а не изъян технологии. Если же проект грамотно построен, минус превращается в плюс. Например, дизайнеры звука могут настроить желаемое поведение звуковым эффектам через редактор Sound Cue. Например, играть случайный звук вместо единственного заданного, выбрать нужный звук в зависимости от внешних условий (скорости передвижения игрока, например) и т.д. В результате у программистов больше времени чтобы писать код и они не отвлекаются на подобные мелочи.


  1. BattleAngelAlita
    29.04.2017 15:19
    -1

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


    1. ASDDeveloper
      29.04.2017 15:22
      +1

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


      1. madMatvej
        01.05.2017 16:39

        В Unity средненький программист может вытворять с графикой довольно многое, и скорости прибавляет не только C# и скрытие рутины за ShaderLab но и встроенный frame debugger. Обидно что нет Occlusion queries, да и instancing появился совсем недавно. я за неделю написал упрощённый clustered forward rendering, только с поинт лайтами(написал бы полноценный но мне и этот не нужен).
        А как с этим дела у Unreal, насколько легко писать шейдера и вообще графику?


    1. Flakky
      29.04.2017 16:50

      Свой просчет освещения можно сделать. Даже на БП, если скилла достаточно. Редактор шейдеров в анриале нодовй, который позволяет очень многое и поддерживает вставки кодом.

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


  1. BattleAngelAlita
    29.04.2017 15:42

    Невозможно например написать свой DOF, невозможно поменять модель освещения, опять же как я говорила — невозможно отрендерить свою шадоу-мапу и сделать EVSM/MSM тени, запустить компьют шэйдер. А в юнити это всё можно без особых усилий.

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


    1. ASDDeveloper
      29.04.2017 15:54
      +2

      Compute шейдеры вполне можно использовать. Сделано даже без модификации движка, см. UE4ShaderPlugin. Но в целом, любой движок стоит выбирать исходя из требований проекта. В Unity, например, годами отсутствовал normal mapping на ландшафте, gpu skinning и instancing. Но разработчики до этого добрались и реализовали.


  1. KwisatzHaderach
    02.05.2017 11:00
    +1

    Интересная статья, далек от геймдева, правда порой лабаю ассеты для Houdini Engine для связки с другим 3д софтом и кто знает чем завтра будешь заниматься, тем паче HE для Unity и для UE присутствует.
    И потому было интересно почитать про Blueprints и код.
    В том же Гудини есть Vex(Cи-подобный язык) и VOP-нетворки(как раз это самое визуальное программирование), который генерит тот же самый vex код(посмотрев который ты можешь переписать на чистом vex если перфекционист или уж так критична скорость).И ситуация такова что ты можешь писать код, тут же обращаться к нему с Vop и наоборот, потому как есть по сути одно целое.Vop удобен как для прототипирования так и в некоторых моментах читаемостью, и наоборот циклы например удобнее реализовать кодом.
    Но никто не заставляет тебя строго использовать тот или иной метод.
    Имхо за этим прекрасное будущее: в скорости и свободе разработки, который дает этот подход.
    И это благо и по причине таковой, что даже простой дизайнер может немного начать разбираться в программировании и слабать нужный инструментарий под себя.
    Стоит ли ожидать наплыва прогеров-индусов от дизайнеров? Очевидно нет.А вот определённую часть работы с прогера они снять могут.


  1. DDDENISSS
    02.05.2017 17:21

    А как обстоят дела с модульностью в анриале?
    В Unity есть лишь Plugins/Standard Assets, Editor и все остальное. Т.е. код в этих папках компилируется в разные сборки. И игровая сборка ничего не знает о других, что предотвращает некоторые ошибки. Но хотелось бы больше возможностей.


  1. Ruddymetor
    05.05.2017 10:54

    Спасибо за советы, начну с Unity!