Traits, как вы уже успели догадаться из прошлых постов — это система скриптов в Armory. Если вы работали с движком Source то наверно помните такие розовые кубики — там они именовались Entities. Так и у нас, суть одна и та же. В нашем случае используемые traits можно посмотреть только в Outliner, переключившившись на режим просмотра Orphan Data в Collections. Это крайне неудобно, потому что нет визуального отображения в скриптов в сцене.
Типы traits
Traits делятся на несколько видов:
-
Haxe — написание скриптов с нуля на Haxe.
-
Wasm — см. WebAssembly.
-
UI — работа пользовательским интерфейсом.
-
Bundled — готовые / связанные сценарии Haxe.
-
Nodes — создание скриптов в Logic Editor (как в blueprints UE4).
Все они могут и (будут!) использоваться в вашем проекте.
Fake User
Если вы написали или составили в Logic Editor traits и не привязали к объекту — при экспорте игры она не сохранится. Чтобы не допустить пропажу ценных часов потраченных на составление хитроумного скрипта, в Blender есть одноименная функция. Нажмите значок щита рядом с вашей trait и она будет экспортирована. Функции или ноды требующих имени, должны быть экспортированы.
Traits Events
Trait могут запускать ивенты с жизненным циклом:
-
Trait.notifyOnAdd() — к объекту добавлен trait.
-
Trait.notifyOnInit() — объект добавлен в сцену.
-
Trait.notifyOnRemove() — объект удаляется со сцены.
-
Trait.notifyOnUpdate() — обновляет логику игры.
-
Trait.notifyOnRender() — обновляет рендеринг.
-
Trait.notifyOnRender2D() — обновляет рендер 2D.
Если сцена построена асинхронно т.е если в ней присутствуют не все объекты, то onInit может добавлять их. Если в сцене у вас есть trait которая зависит от других объектов, то используйте Scene.active.notifyOnInit() — этот ивент вызывается когда сцена полностью построена и в ней присутствуют все необходимые объекты.
Свойства traits
Скриптам можно задавать параметры и свойства прямо из Blender. Перед переменной в исходном коде нужно вставить метаданную @prop. Переменная var поддерживается только с ключевым словом. Final не будет работать, потому что свойства trait устанавливаются через Haxe Reflection API, после сборки игры.
Поддерживаются следующие типы данных:
-
Примитивные:
-
Int
-
Float
-
Boolean
-
-
String
-
Типы данных объекта
-
Плавающие векторы:
Пример исходного кода:
Код
package arm;
// See below ("Object data types")
import iron.object.CameraObject;
import iron.math.Vec2;
import iron.math.Vec3;
import iron.math.Vec4;
class MyTrait extends iron.Trait {
// Primitive data types
@prop
var intValue: Int = 40; // Type annotation possible, but not required
@prop
var floatValue = 3.14;
@prop
var stringValue = "Hello world!";
@prop
var booleanValue = true;
// Object data types
@prop
var objValue: iron.object.Object; // Needs type annotation to be recognized
@prop
var camObjValue: CameraObject; // Type can be imported (see above)...
@prop
var lightObjValue: iron.object.LightObject; // .. or not, both will work
@prop
var meshObjValue: iron.object.MeshObject;
@prop
var speakerObjValue: iron.object.SpeakerObject;
// Vector data types
@prop
var vector2DValue: Vec2 = new Vec2(0.2, 0.5); // Initialization possible...
@prop
var vector3DValue: Vec3; //... but not required
@prop
var vector4DValue = new Vec4(1, 2, 3, 4);
// Not visible in Blender, `@prop` is missing
var notVisibleValue = 0.0;
// ...
}
Вот что дает этот исходник:
Предупреждения и ошибки
Движок будет предупреждать о неверных @prop:
-
Каждый @prop должен объявлять следующую переменную
-
Должна быть поддержка свойств
-
Синтаксис свойств должен быть правильным
-
Не лучшим решением будет делать статические свойства, потому что несколько объектов могут записать одно и то же свойство, что может привести к ошибкам.
Упорядочивание
По дефолту все traits создаются и хранятся в папке sources/ arm. Сваливать все в одну кучу — не самое умное решение, вам же потом поддерживать проект и искать битый скрипт среди сотен других — то еще занятие. Сохранять лучше в отдельных папках и подпапках для каждой сцены.
Можно упорядочить иерархически, для этого используем Haxe package syntax при наименовании какой нибудь traits. Например создадим trait с именем general.BoxBehavior — она сохранится в подкаталоге Sources/arm/general с именем «BoxBehavior.hx»
Вложенные подпапки можно создавать бесконечно, добавляя имя traits через точку: «general.terrain.TerrainCollider» создаст файл с именем «TerrainCollider.hx» по пути «Sources/arm/ general/terrain».
Если вдруг понадобилось присвоить объекту другую характеристику, то нажмите на Class под списком свойств и выберите в выпадающем списке необходимое имя.