Files

42 KiB
Raw Permalink Blame History

id, title
id title
animation Анимация

Анимация

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

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

func OnAnimEvent(id int, payload float) {
  if anim.EventName(id) == "Hit" {
    node.Child("Sword").Get<Hitbox2D>().Pulse()
  }
}

id: animation/clips title: Клипы

Клипы

Клип — это файл .aeanim в папке ассетов. У него есть длина в секундах, режим повтора (once, loop, pingPong) и дорожки:

anim version=1 length=0.6 loop=loop {
  frames "" fps=10 {
    sprites=[asset("…run_0"), asset("…run_1"), asset("…run_2")]
  }
  track "" prop="SpriteRenderer.tint" kind=color {
    key t=0 v=[1, 1, 1, 1] interp=linear {}
    key t=0.3 v=[1, 0.6, 0.6, 1] {}
  }
  track "Arm" prop="transform.rotation" kind=float32 authority=simulation {
    key t=0 v=0 {}
    key t=0.3 v=0.8 tangent=linear {}
  }
  event t=0.3 name="Hit" payload=1 {}
}
Часть Значение
метка track узел в виде пути от узла проигрывателя; "" — сам узел
prop свойство, с путями как у твинов: Component.Field, Component.Field.a, transform.position, script/Name.Field
kind тип значения: float32, int32, bool, enum, vec2, vec3, vec4, color, rect, quat, assetRef
authority presentation (по умолчанию) или simulation, см. Время и источник истины
onEnd hold оставляет последнее значение, когда клип заканчивается или останавливается, restore возвращает значение, которое было до запуска игры
root=true только для "" с prop="transform.position" и kind=vec2: дорожка не записывается; вместо этого «Аниматор» с «Движением корня» двигает узел на её изменение
key t, v и interp=bezier (по умолчанию), linear или step; tangent=auto, linear или free с in и out
frames кадры спрайта: sprites и fps или durations, flipX по желанию; превращается в ступенчатые дорожки на SpriteRenderer.sprite и SpriteRenderer.flipX
event событие в момент t с объявленным name, необязательными payload и mode

Числа, векторы и цвета интерполируются; повороты в виде кватернионов идут по короткой дуге; int переключается ступенями, если у дорожки нет numeric=true; bool, enum и ссылки на ассеты переключаются ступенями. Спрайты — это ассеты спрайтов, обычно из группы атласа.

Движок поставляется с четырьмя клипами для тестов и набросков: engine/anim/run — восемь кадров бегущей фигуры (с engine/sprites/runner_0 по _7) с двумя событиями отображения Footstep; engine/anim/bob — покачивание transform.rotation в симуляции с игровым событием Hit на правом повороте; engine/anim/jump — поза бегуна в шаге; engine/anim/hit — один взмах transform.rotation за 0,3 с. Встроенный контроллер играет jump в состоянии Jump и hit в состоянии Hit.

Клип, который не импортируется, сохраняет свою последнюю исправную версию, а ошибка появляется в «Проблемах»: ANM001 — дорожка или файл, которые импортёр не может прочитать, ANM002 — ключ или событие за пределами длины, ANM003 — необъявленное событие.


id: animation/player title: Проигрыватель анимации

Проигрыватель анимации

Проигрыватель анимации воспроизводит свой «Клип» с начала игры, если включено «Запуск при старте». «Скорость» масштабирует время; отрицательная скорость воспроизводит назад. «Повтор» заменяет режим повтора клипа.

В «Попробовать» бегун воспроизводит встроенный клип бега, а маятник — отдельный клип покачивания. Нажмите R, чтобы повторить бег, или B, чтобы изменить направление; скрипты показывают события отображения и игровые события.

Метод
Play(clip) запускает клип с начала; nil снова воспроизводит текущий клип
Stop() завершает клип; дорожки restore получают старые значения, выполняется Finished(-1)
Pause(), Resume() приостанавливает и продолжает
Seek(t) переходит к моменту клипа, не вызывая событий между ними
SetSpeed(s) меняет скорость
Сигнал
Finished(cycle int) закончился клип без повтора (0) или вызван Stop (-1)
Event(id int, payload float) клип дошёл до события

Команды вступают в силу на следующем фиксированном шаге, поэтому скрипт может вызывать их из Update. «Время», «Играет» и «Цикл» показывают состояние во время игры.

Дорожка, узел которой отсутствует (ANM005) или свойство которой не совпадает с её типом (ANM001), выключена; остальной клип воспроизводится. Когда клип импортируется снова с теми же дорожками, проигрыватели сохраняют своё место; с другими дорожками они останавливаются (ANM008).


id: animation/time title: Время и источник истины

Время и источник истины

Проигрыватель в игровом времени продвигается фиксированными шагами и стоит, пока игра на паузе. На каждом шаге он записывает свои дорожки по времени клипа этого шага. Одно исключение: дорожки трансформации 2D-узла с authority=presentation (по умолчанию) показываются в момент между двумя шагами, поэтому движение остаётся плавным при любой частоте кадров и не меняет позицию узла в игре.

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

Анимация и другие системы никогда не управляют одним свойством вместе:

  • Твин свойства, которым управляет анимация, останавливается с Completed(false).
  • Дорожка трансформации узла с «Движением 2D» или вторая дорожка свойства, которым управляет другая дорожка, выключена (ANM004).
  • На динамическом теле выключены все дорожки трансформации; на кинематическом теле выключена дорожка трансформации отображения; статическое тело предупреждает, что его телепортируют (ANM006).

Со «Шкалой времени» unscaled проигрыватель идёт в реальном времени и продолжает играть, пока игра на паузе, — для меню и другого отображения. Он не входит в состояние игры: дорожки симуляции выключены, а игровые события приходят как события отображения (ANM007).


id: animation/events title: События

События

События объявляются в Настройках проекта → Анимация или в project.aego:

animation {
  event "Hit" payload=float {}
  event "Footstep" {}
}

Footstep и Hit (данные float) объявлены движком для его встроенных клипов; проект может использовать их без объявления.

У события в клипе есть режим:

Режим Когда срабатывает
gameplay (по умолчанию) на фиксированном шаге, который его пересекает, один раз за цикл, одинаково при каждом повторе
presentation когда его пересекает отрисованное время; для звуков и эффектов; не во время повтора
preview только в предпросмотре редактора

Скрипты узла проигрывателя получают OnAnimEvent(id int, payload float), а проигрыватель испускает свой сигнал Event(id, payload). Событие в момент 0 срабатывает, когда клип начинается, и в каждом новом цикле; событие в конце срабатывает один раз за цикл. Шаг, который покрывает несколько циклов, вызывает каждое событие один раз за цикл, по порядку. Seek ничего не вызывает.


id: section/animation title: Анимация

Блок animation в project.aego принадлежит модулю Animation.

События анимации

Объявляйте имена событий проекта в блоке animation. Footstep и Hit встроены в движок; повторное объявление не заменяет встроенное событие. Имя каждого события проекта должно быть непустым и уникальным. Необязательный payload принимает none, int, float или bool; по умолчанию — none.

animation {
  event "Land" payload=float {}
  event "OpenDoor" {}
}

В Настройках проекта → Анимация добавляйте, переименовывайте и удаляйте события проекта и выбирайте тип данных. Изменения остаются в черновике настроек до нажатия Применить; для черновика работают Undo и Redo. Новые объявления действуют при следующем запуске игры. При переименовании или удалении объявления клипы автоматически не меняются: обновите имена их событий отдельно.

Клипы ссылаются на эти имена. Скрипты получают OnAnimEvent(id, payload) и могут преобразовывать имена через anim.EventName и anim.EventID; см. События анимации. Тот же блок можно редактировать и в project.aego.


id: animation/animator title: Аниматор

Аниматор

Аниматор воспроизводит состояния контроллера — файла .aectrl: у каждого состояния есть клип, а переходы переключают состояния, когда меняются параметры. Скрипты задают параметры; остальное делает граф.

В «Попробовать» используйте A/D для движения, Space для прыжка и J для удара. Скрипт задаёт параметры контроллера и показывает текущее состояние.

func FixedUpdate(dt float) {
  m := node.Get<Motion2D>()
  a := node.Get<Animator>()
  a.SetFloat("Speed", math.Abs(m.Velocity.X))
  a.SetBool("Grounded", m.Grounded)
  if input.Pressed("Attack") {
    a.SetTrigger("Attack")
  }
}
Метод
SetBool, SetInt, SetFloat(name, value) задаёт параметр; переходы читают его на следующем фиксированном шаге
SetTrigger(name), ResetTrigger(name) одноразовый параметр: его сбрасывает переход, который его использует, или конец этого шага
GetBool, GetInt, GetFloat(name) читает параметр
Play(state) переключает на состояние на следующем фиксированном шаге, без смешивания
CrossFade(state, seconds) плавно переходит в состояние
IsState(name) bool, StateName(index) string текущее состояние или имя состояния по индексу
Сигнал
StateEntered(state int) начался переход в состояние
StateExited(state int) состояние перестало играть, в конце смешивания
Event(id int, payload float) состояние дошло до события своего клипа

«Состояние», «Время», «Прогресс» и «Смешивание» показывают состояние во время игры. Создать → Геймплей → Персонаж платформера приходит с «Аниматором» на встроенном контроллере engine/anim/platformer: Idle, Run, Jump и Hit, с параметрами Speed, Grounded и Attack.

Задавайте параметры в FixedUpdate, когда они берутся из состояния игры, как выше: граф идёт фиксированными шагами, поэтому видит те же значения при каждом повторе с любой частотой кадров.

«Аниматор» и «Движение 2D» вместе

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

func FixedUpdate(dt float) {
  m := node.Get<Motion2D>()
  m.Move(input.Axis("Move"))
  if input.Pressed("Jump") {
    m.Jump()
  }
  a := node.Get<Animator>()
  a.SetFloat("Speed", math.Abs(m.Velocity.X))
  a.SetBool("Grounded", m.Grounded)
  a.SetFloat("VerticalSpeed", m.Velocity.Y)
  if input.Pressed("Attack") {
    a.SetTrigger("Attack")
  }
}

Значения описывают предыдущий шаг: скрипты выполняются до того, как двигается «Движение 2D». Урон доходит до аниматора через сигнал, Health.Damaged → SetTrigger("Hurt"), а переход any с interrupt=true показывает его даже посреди смешивания. «Отразить по X» спрайта остаётся за скриптом: оно следует за вводом, а не за клипом.

В examples/topdown работа разделена иначе: «Машина состояний» решает, что делает враг (Patrol, Chase, Dead), а её обработчики только задают параметры «Аниматора» (Chasing, Die); клипы решают, как он выглядит.


id: animation/controller title: Контроллеры

Контроллеры

controller version=1 {
  entry="Idle"
  param "Speed" kind=float {}
  param "Grounded" kind=bool default=true {}
  param "Attack" kind=trigger {}
  state "Idle" clip=asset("…idle") {}
  state "Run" clip=asset("…run") speed=1.2 {}
  state "Hit" clip=asset("…hit") loop=once events=both {}
  transition "Idle" to="Run" duration=0.1 {
    cond "Speed" op=gt value=0.1 {}
  }
  transition "Run" to="Idle" duration=0.1 {
    cond "Speed" op=le value=0.1 {}
  }
  transition "any" to="Hit" interrupt=true {
    cond "Attack" {}
  }
  transition "Hit" to="Idle" exitTime=1 duration=0.05 {}
}
Часть Значение
param kind — это bool, int, float или trigger; default для первых трёх
state clip, speed, loop (once, loop, pingPong; по умолчанию из клипа), events (см. ниже)
entry состояние, с которого начинает аниматор
transition "From" to="To" "any" в качестве источника уходит из любого состояния, кроме цели
cond op — это eq, ne, gt, ge, lt или le со value; без op bool или триггер должен быть установлен
duration секунды смешивания; 0 переключает сразу
exitTime переход ждёт, пока состояние не проиграет столько проходов своего клипа: 1 — один проход
interrupt переход может прервать идущее смешивание

На каждом фиксированном шаге аниматор продвигает свои состояния, затем ищет переход: сначала переходы any по порядку, затем переходы текущего состояния. Все условия должны выполняться. Во время смешивания рассматриваются только переходы с interrupt. Переходы без длительности могут следовать друг за другом, до восьми за один шаг; переход с длительностью завершает шаг. Импортёр проверяет имена, операторы и циклы мгновенных переходов (ANC001, ANC002, ANC003, ANC005); состояние, клип которого отсутствует, ничего не воспроизводит (ANC004).

Смешивание

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

События во время смешивания

events входящего состояния Какие события срабатывают
dominant (по умолчанию) события состояния, вес которого в момент события не меньше половины
both события обоих состояний
incoming только события входящего состояния

Событие в начале входящего состояния происходит при весе 0, поэтому с dominant оно принадлежит уходящему состоянию: ставьте удар атаки туда, где атака уже видна полностью.


id: animation/root title: Движение корня

Движение корня

Клип может двигать самого персонажа: его дорожка корня — track "" prop="transform.position" kind=vec2 root=true. «Аниматор» не записывает эту дорожку; он двигает узел на столько, на сколько дорожка меняется за каждый шаг, поэтому цикл ходьбы продвигает персонажа, а не отбрасывает его назад на каждом повторе.

«Движение корня» Что движется
none ничего; дорожка корня не используется
toMotion узел, через его «Движение 2D»: стены его останавливают, склоны и ступени несут, скорость остаётся прежней
toTransform позиция узла; кинематическое тело двигается своей скоростью

«Масштаб корня» умножает движение в пространстве родителя: задайте его X равным -1, пока персонаж смотрит влево, потому что отражение спрайта не поворачивает узел. С toMotion и без «Движения 2D» на узле «Корень без Движения 2D» двигает вместо него трансформацию; без него движение отбрасывается (ANM009). Во время смешивания движение двух состояний смешивается по его весу. Движение корня работает только в игровом времени.


id: animation/go title: Go

Go

p, _ := sdk.Get[sdk.AnimationPlayer](scene, node)
p.Play(sdk.AnimClip{ID: runClip})
sdk.AnimationOf(ctx).SetParam(hero, "Speed", 3)

sdk.AnimationOf(ctx) возвращает сервис игрового мира; SetParam(node, name, value) задаёт параметр «Аниматора» по имени, true и false как 1 и 0. Системы animation.fixed (PrePhysics, после script.fixed и якоря engine.intents, до engine.motion) и animation.sample (Animation, всегда) продвигают и рисуют проигрыватели и аниматоры. Система Go, которая задаёт параметры или команды, выполняется до engine.intents; система, которая читает движение корня, выполняется после engine.motion.

Движение корня доходит до персонажа через контракт motion2d.receiver (contracts/motion2d), который предоставляет «Движение 2D»; его может предоставить и другой контроллер.


id: animation/attack title: Атака с кадром удара

Атака с кадром удара

Урон атаки принадлежит одному кадру её клипа, а не нажатию кнопки: поставьте на этот кадр игровое событие и запускайте импульс хитбокса, когда оно приходит.

anim version=1 length=0.3 {
  frames "" {
    sprites=[asset("…swing_0"), asset("…swing_1"), asset("…swing_2")]
    durations=[0.06, 0.06, 0.18]
  }
  event t=0.1 name="Hit" payload=1 {}
}

Контроллер входит в атаку из любого состояния по триггеру и выходит после одного прохода:

transition "any" to="Hit" interrupt=true {
  cond "Attack" {}
}
transition "Hit" to="Idle" exitTime=1 duration=0.05 {}

Скрипт нажимает триггер и превращает событие в урон:

func Ready() {
  hit = anim.EventID("Hit")
}

func OnAnimEvent(id int, payload float) {
  if id == hit {
    Slash.Get<Hitbox2D>().Pulse()
  }
}
  • Задайте «Хитбоксу 2D» active=false и policy=oncePerActivation: Pulse наносит один раунд урона, поэтому каждая атака бьёт каждую цель один раз.
  • Второе нажатие во время атаки ничего не делает, потому что переход any никогда не уходит из своей же цели.
  • Это игровое событие: оно срабатывает на фиксированном шаге, который его пересекает, одинаково при каждом повторе.
  • Оставьте переход в атаку без duration: при правиле событий по умолчанию событие во время смешивания принадлежит стороне с большим весом, и событие в начале плавного появления ушло бы уходящему состоянию.

id: animation/panel title: Панель «Анимация»

Панель «Анимация»

Клип атаки в предпросмотре: игрок делает выпад, а дуга удара показывает свой полный кадр

Окно → Анимация редактирует клип «Проигрывателя анимации» выбранного узла или клипы контроллера его «Аниматора». Создать → Анимация → Клип (Ctrl+Shift+N, clip, Enter) создаёт односекундный повторяющийся клип рядом со сценой и даёт узлу без проигрывателя проигрыватель, который его воспроизводит; Создать → Анимация → Контроллер делает то же с «Аниматором» и контроллером с одним состоянием Idle. Файл новый, поэтому шагом отмены становится только добавленный компонент.

Предпросмотр показывает клип на узле в момент курсора времени, не трогая сцену: сохранения, игра и отмена видят значения, которые действительно есть в сцене. Поля, которыми управляет клип, становятся в Инспекторе доступными только для чтения, с жёлтой полосой и подсказкой «управляется клипом». Запись превращает правки в ключи: значение, введённое в Инспекторе, или перемещение на панели «Сцена» ставит ключ у курсора, а не меняет сцену. Когда «Автоключ» выключен, нажмите K.

Таблица ключей показывает по строке на дорожку и ромб на ключ; дорожки спрайтов показывают кадры миниатюрами, когда хватает места. Перетаскивайте ключи, чтобы двигать их, тяните линейку, чтобы перематывать, дважды щёлкните дорожку событий, чтобы добавить событие. Колесо масштабирует время вокруг мыши, Shift+колесо сдвигает. Кривые рисует выбранную числовую дорожку кривой, по одной компоненте за раз (x/y, r/g/b/a); перетаскивайте точки и ручки касательных, дважды щёлкните, чтобы добавить ключ, щёлкните правой кнопкой, чтобы удалить. Всё перетаскивание — один шаг отмены, а остальные компоненты отредактированного ключа сохраняют свои значения.

Клавиша Действие
Space воспроизводит клип или ставит его на паузу
K ставит ключи на все поля выбранного узла, значение которых отличается от клипа у курсора
Delete удаляет выбранные ключи
Ctrl+C, Ctrl+V копирует ключи и вставляет их у курсора; вставка в другой клип создаёт недостающие дорожки

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

Перетащите спрайт или ячейки листа из «Ассетов» на дорожку спрайта, чтобы поставить на них ключи: первый встаёт там, где вы отпустили, остальные идут следом по одному на 1/12 с, а клип удлиняется, если они выходят за его конец. В «Кривых» график делит линейку с таблицей ключей, поэтому ключ стоит под своим временем.

Чтобы скрыть спрайт на часть клипа, поставьте ключ его tint с прозрачным цветом: #00000000 и #ffffff00 оба ничего не рисуют при любом режиме смешивания. Затухание от #ffffffff к #ffffff00 оставляет цвет белым, пока он гаснет; затухание к #00000000 проходит через серый. Так атака платформера показывает свою дугу удара, а скрипт игрока снова прячет дугу, когда атака прерывается.

В «Предпросмотре» и «Записи» панель «Сцена» рисует путь дорожки transform.position узла, с ключами в виде точек: перетащите точку, чтобы сдвинуть этот ключ. События предпросмотра вспыхивают на пути, когда воспроизведение их пересекает. Пока вы тянете гизмо перемещения в «Записи», узел следует за мышью, а не за клипом, и ключ ставится, когда вы отпускаете кнопку.


id: animation/sheets search_names: [нарезать спрайты, нарезка спрайтов, спрайтшит, покадровая анимация] title: Листы спрайтов и покадровая анимация

Листы спрайтов и покадровая анимация

Выберите PNG в «Ассетах», чтобы открыть его инспектор: лист с его ячейками.

  • Нарезать по сетке вырезает ячейки одного размера, после смещения и с отступами между ними, ряд за рядом. Количество останавливает нарезку после стольких ячеек.
  • Нарезать по альфе находит каждую отдельную фигуру, у которой альфа выше порога, и упорядочивает их рядами сверху, каждый ряд слева.
  • Нарезать записывает ячейки в .meta листа. Каждая ячейка становится ассетом спрайта с именем вида assets/hero.png#hero_000 и собственным id. Отмена возвращает прежние ячейки.

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

Инспектор листа: настройки импорта, ячейки и настройка нарезки

Раздел Импорт над листом редактирует, как импортируется PNG: фильтр (nearest для пиксель-арта, linear для гладкой графики), sRGB, MIP-уровни, группа атласа с её отступами и выдавливание краёв. Изменения ждут Применить, которое переписывает .meta и заново импортирует текстуру; Вернуть отбрасывает их. «Применить» — один шаг отмены того же вида, что и нарезка, поэтому отмена восстанавливает и настройки, и ячейки в том порядке, в котором вы их меняли.

В «Ассетах» у нарезанного листа на плитке есть стрелка: она раскрывает ячейки сразу после листа, каждую с миниатюрой. Выделите ячейки через Ctrl+щелчок и Shift+щелчок, затем Покадровая анимация из выделения использует их в порядке имён. Перетащите ячейку на поле sprite в Инспекторе или на дорожку спрайта в панели «Анимация». Ячейки нельзя переименовать, переместить или удалить по отдельности: вместо этого нарежьте лист заново.

Чтобы анимировать кадры, выберите узел, оставьте лист выбранным в «Ассетах» (или открытым в инспекторе) и выберите Создать → Анимация → Покадровая анимация из выделения (Ctrl+Shift+N, flip, Enter). Клип показывает ячейки одну за другой с частотой 12 кадров в секунду, как ступенчатые ключи на SpriteRenderer.sprite. Если у «Проигрывателя анимации» узла уже есть клип, кадры попадают в этот клип; иначе рядом со сценой создаётся новый повторяющийся клип с «Проигрывателем анимации», который его воспроизводит. Панель «Анимация» показывает кадры миниатюрами.


id: animation/animator-panel title: Панель «Аниматор»

Панель «Аниматор»

Панель «Аниматор» с контроллером платформера

Окно → Аниматор показывает контроллер «Аниматора» выбранного узла в виде графа: по блоку на состояние, метка Вход, которая указывает на состояние, с которого начинает «Аниматор», и метка Любое состояние для переходов, которые могут уйти из любого состояния. Стрелки — это переходы, подписанные своими условиями; два перехода между одними и теми же состояниями в противоположных направлениях расходятся дугами. Колесо масштабирует вокруг мыши; тяните фон или держите среднюю кнопку, чтобы сдвинуть вид; Показать всё в меню фона вписывает граф.

Перетащите состояние, «Вход» или «Любое», чтобы передвинуть его; позиция сохраняется как pos состояния и entryPos / anyPos контроллера, поэтому раскладка графа хранится в файле. Протяните от точки справа у состояния (или у «Любого») к другому состоянию, чтобы добавить переход. Щёлкните фон правой кнопкой, чтобы добавить состояние или запустить Авторасстановку, которая ставит все состояния столбцами от входа. Щёлкните состояние правой кнопкой, чтобы сделать его входом или удалить вместе с его переходами; щёлкните переход правой кнопкой, чтобы поднять или опустить его или удалить.

Левая сторона редактирует выделение: клип и скорость состояния или длительность, время выхода, флаг прерывания и условия перехода. Переходы проверяются по порядку, поэтому стрелки ↑ ↓ рядом с заголовком переносят выбранный переход раньше или позже. Под инспектором — параметры; + добавляет параметр любого типа, − удаляет его.

Каждое изменение — один шаг отмены в файле контроллера. Изменение, сделанное вне редактора, в текстовом редакторе или через aego mcp, появляется, как только файл заново импортирован.

Во время игры состояние, в котором находится «Аниматор», подсвечено кольцом, которое заполняется по мере воспроизведения клипа, а параметры становятся живыми: введите float, переключите bool или нажмите Сработать для триггера, чтобы управлять идущей игрой.