Создание уровня в Armory

80328a209e3a4f2f7811e4345a068124.png

Привет! В предыдущем посте я рассказал вам о движке Armory, теперь создадим свой первый уровень в нем. На самом деле, создание уровней в Armory ничем практически не отличается от работы в том же Unreal или Unity — вы также можете импортировать ассеты, создавать свои тут же (это же Blender!), накладывать текстуры и прочие штуки. Как я уже упоминал, для работы с движком вам нужны умение работы с Blender, поскольку Armory тесно связан с ним. Я не стану подробно разбирать как добавить plane, cube или lamp в сцену — только работа с движком. Готовы? Тогда начнем.

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

Панель Armory Player:

  • Runtime:

  • Camera:

    • Scene чтобы начать игру с точки активной камеры сцены.

    • Viewport, чтобы начать игру из области просмотра. Это полезно для предварительного просмотра сцены, так как позволяет управлять камерой.

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

045c36b8cb9d2fbdd9a941da07353dc2

В сцене присутствует Cube, Cylinder, Ground, Lamp, Wall, Lamp (spot) и анимированная модель человека и цилиндра. Вам понадобятся для сцены еще и две текстуры (grid_base, grid _rough), но вы можете взять любые другие или сгенерировать свои. Сделали? Приступим.

Анимация

Наша сцена, в отличии от неподвижного рендера, интерактивна — куб в центре вращается, цилиндр катается, человек бежит, кубы у стены можно перетаскивать, а кнопкой F можно заспавнить новые кубы. И вот тут самое интересное — все сделано силами Blender. Начнем с анимации вращения куба в центре.

Выберете куб, в панели Timeline перейдите к кадру 1, выберите куб и нажмите, I — Rotation чтобы вставить ключевые кадры для поворота. Затем перейдите к 60 кадру на временной шкале. Выбрав куб, нажмите  R чтобы повернуть его на желаемую величину и нажмите  I — Rotation еще раз. Наш куб анимирован.

Физика объектов

Выбрав объект (Cube), перейдите на Physics вкладку и нажмите Rigid Body. Задать форму для объекта можно на панели Collision.

906a9002a4d2ac8a0435867846258c99.png

В панели Rigid Body задаем массу и тип объекта:

  • Active для объектов, на которые влияет физика.

  • Passive для статических или анимированных объектов на шкале времени.

Освещение и мир

98cdfd0abbdd19886b449644172462cc.png

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

Мир настраивается в Shader Editor — World. Можно сделать процедурное небо или добавить какой-нибудь HDR файл.

eb16796e7354bcd62d19ebf8710f478a

Логические узлы

Выше я рассказал как устроена наша сцена, теперь добавим в нее интерактивность. За это у нас отвечают Logic Node — аналог blueprints в Unreal Engine 4. Созданные в редакторе ноды компилируются в скрипты. Их можно писать на Haxe и/или комбинировать оба этих способа.

Система скриптов состоит из 5 основных категорий:

  • Events — ноды которые запускают необходимое событие.

  • Actions — при запуске этой ноды (events) начинается действие.

  • Logic — ноды для управления потоком, используя ветвления, циклы, вентили…

  • Variables — ноды используемые для хранения данных в логическом дереве.

  • Values — ноды для извлечения данных из других объектов.

Процедурную анимацию цилиндра сделаем с помощью нодов. Открываем Logic Editor — New для создания нового дерева узлов. Все доступные ноды находятся в диалоговом  меню Shift — A.

12b3aa1edd63c18f475a2aca5a64c204.png

  • Найдите On Update узел и вставьте его. Он будет активировать свой вывод каждый кадр.

  • Подключите его к входу In Set Object Location узла. Если оставить Object поле пустым, будет использоваться объект, выполняющий это логическое дерево. В нашем случае это цилиндр.

    Красные входы узлов (часто называемые In и Out) используются для потока сигналов дерева узлов. Красные входные гнезда активируют узлы, а красные выходные гнезда обычно активируются при выполнении узла (если узел не указывает иное). Другие типы входов (другие цвета) используются для передачи данных между узлами.

  • Добавьте нод Vector и подключите его выход Location к входу Set Object Location узла. Теперь положение цилиндра будет установлено на этот векторе в каждом кадре.

  • Для местоположения вектора X, добавьте нод Math и установите его на Sine.

  • Вставьте Get Application Time для управления синусоидальным узлом — он перемещает цилиндр вперед и назад.

  • Добавьте еще один Math для масштабирования синусоидального выхода (это позволит цилиндру двигаться дальше с каждой стороны).

  • Положение Y и Z сохраняем без изменений, поэтому нам нужно установить его в соответствии с текущим положением цилиндра. Добавьте Get Object Location, подключите его к Separate XYZ узлу, чтобы разбить вектор на его значения XYZ, а затем подключите значения Y и Z к входам Y / Z Vector узла, который мы добавили ранее.

Консоль отладки можно включить в Armory Project > Flags > Debug Console.

Haxe

07f4b55a9ad42742dfc115935ef14946

Спавн кубов кнопкой «F» мы напишем на Haxe. Создадим в сцене еще один куб, добавим в сцену, настроим ему физику (Rigid Body и Active). Добавим Empty, расположим на некоторой высоте от сцены — это точка спавна наших кубов. Создайте новый Haxe traits в Properties — Object — Armory Traits. Нажмите кнопку New Script. Откроем Kode Studio — создадим и сохраним новый скрипт.

package arm;

import iron.object.Object;
import iron.system.Input;
import iron.Scene;
import armory.trait.physics.RigidBody;

class SpawnBox extends iron.Trait {
	public function new() {
		super();
		// We want to get notified every frame
		notifyOnUpdate(update);
	}

	function update() {
		// f key was pressed
		if (Input.getKeyboard().started("f")) {
			// Spawn Box object
			Scene.active.spawnObject("Box", null, boxSpawned);
		}
	}

	// Box just got spawned
	function boxSpawned(o:Object) {
		// Translate cube to the location of empty object
		var traitOwner = object;
		o.transform.loc.setFrom(traitOwner.transform.loc);
		// Box object has a rigid body trait
		// Notify physics system to take new location into effect!
		o.getTrait(RigidBody).syncTransform();
	}
}

В Armory уже есть готовые пресеты скриптов. Обычный скрипт может прикрепляться к встроенному объекту traits. В этом туториале мы будем  использовать PhysicsDrag traits. Эта traits позволит нам перетаскивать объекты мышью.

Armory UI

04d14da9f9ff1c7e2d9b69d9a2ac23e2.jpg

Игровой интерфейс создается в специальном инструменте — Armory UI. чтобы создать UI, переключаемся на вкладку Scene, добавляем traits UI в панели Armory Traits. Нажимаем New Canvas и Edit Canvas — запустится редактор интерфейса. Далее в Armor UI нажав кнопку Text создаем текстовый объект. Отрегулировать можно на панели Properties. Сохраняем.

Путь рендеринга

154c8cc4df7c6e8826ccff00354211c7.jpg

В Аrmory есть настраиваемая система рендеринга, впанели Render — Armory Render Path можно выбрать одно или несколько целевых устройств для сборки. Там же можно настроить качество графики.

Экспорт проекта

5c35c8f761c9a46b672ec1acf78a3d3a.png

Сборка и публикация нашего проекта находится в Properties — Render — Armory Exporter. Можно сделать несколько предустановок экспорта, причем в каждой можно указать платформу, API, путь и сцену для запуска. Выберете необходимую платформу (например Windows) и нажмите Publish. Экспортированные и собранные файлы можно посмотреть нажав треугольник (выделен красным) — Open Folder.

© Habrahabr.ru