Behavior trees, Task planning, Neural networks

Форум для всего, что связано с ИИ.

Behavior trees, Task planning, Neural networks

Сообщение Strannik 04 май 2013, 22:41

Интересуюсь архитектурой AI в играх, да и в целом упрощением организации кода.
Хочу поделиться тем, что нашел, и узнать что-нибудь новое для себя.

Для начала, видео:
Дмитрий Минский - Behavior trees на практике
http://it.tut.by/336603

И статейка на хабре: http://habrahabr.ru/post/173187/

Было бы интересно узнать, кто что использует при разработке больших игр:
плагины какие-нибудь, типа Rain{One}, Behave.
собственную разработку с использованием деревьев решений или планировщиков; используется ли визуализация графов в данном случае.


Перечень найденных мною AI плагинов к unity (обычные стейт машины не рассматривал, так как инфы по ним навалом):

Деревья решений (описания минусов местами может быть ошибочным, так как пока поверхностно разбирался):
1) Rain{Indie}, Rain{One}
Плюсы: неплохая документация, actions пишутся отдельными скриптами, генерация кода экшенов из шаблонов.
Минусы: все еще нет отображения текущего состояния в графе; переменные в графе можно писать только текстом (нет их добавления для дальнейшего выбора, как например в Mecanim), отсутствуют проверки существования переменных; вместо того, чтобы, использую drag-and-drop, связывать скрипты с экшенами, приходится прописывать их имена вручную; предположительно используется рефлексия, из-за чего предполагается не очень хорошая скорость;
2) Behave
Плюсы: есть отображение текущего состояния в графе,
Минусы: практически все те же, что у Rain. Вдобавок экшены пишутся в одном скрипте для конкретного дерева, что крайне плохо; скудная документация.
3) React - не рассмотрен
4) AI Behavior - не рассмотрен
5) Skill Studio - не рассмотрен

Планировщики:
1. В Rain{One} есть Goal Oriented Behavior.
2. ithink-unity3d (https://code.google.com/p/ithink-unity3d/) - в процессе разработки, насколько я понял.

Нейронные сети:
1. Neural Nets
2. Neural Network AI extension


Дополнительная инфа (сюда периодически буду скидывать ссылки на интересные материалы):
1. http://www.bth.se/fou/cuppsats.nsf/all/ ... _games.pdf
2. http://gamebrains.ca/377/Lecture%20Materials/
3. http://gamebrains.ca/377/Lecture%20Mate ... lides.pptx
4. http://www.packtpub.com/unity-4-x-game- ... mming/book (книга по AI и AI плагинам на unity)
5. http://web.media.mit.edu/~jorkin/goap.html
6. http://www.dis.uniroma1.it/~degiacom/di ... os-vassos/
7. http://igda.sakura.ne.jp/sblo_files/ai- ... 2_2_25.pdf (различные схемы архитектур AI из реальных проектов)


Вообще, начав изучать все это, начал понимать, что большую часть логики игры (не только AI) лучше реализовывать на графах.
Но к сожалению, насколько я вижу, в подавляющем большинстве игровых компаний (по крайней мере в компаниях, разрабатывающих на unity) в России кодят по старинке.
Strannik
UNIт
 
Сообщения: 93
Зарегистрирован: 26 апр 2012, 22:30
Откуда: Омск

Re: Behavior trees, Task planning, Neural networks

Сообщение Alex3D 28 июн 2013, 00:37

Всем доброго времени суток!
Вот решил перевести и прокомментировать элементы Behavior Tree из Rain{Indie}. Замечания и исправления приветствуются.

КОНТЕЙНЕРЫ (Containers)

Behavior Tree Root
(Корень дерева поведений)

Его имя - это и имя всего дерева поведений, и файла этого дерева. Указывается при создании, потом изменить это имя нельзя.
Предназначен для инициализации переменных. Занести значения в виде строк true или false не удалось, надо заносить их в виде целочисленных аналогов - 1 и 0.
Если в Mind.RootName объекта ИИ ничего не указано, то автоматически выполняется первый вложенный в корень узел. Редактор позволяет заносить для Корня несколько child'ов, и выполнение можно начать с любого из них, указав нужное имя в Mind.RootName.
Важно! - выполнение можно начать только с child'а ПЕРВОГО уровня вложенности - если указать что-то другое (или вообще ошибочное имя), то никакой ошибки в среде не индицируется, однако ничего и не выполняется.

Sequencer
(Пошаговый)

Выполняет все вложенные узлы по порядку, пока какой-либо из них не завершится Failure (тогда возвращает Failure), либо пока все они успешно не завершатся (тогда возвращает Success).

Selector
Переключатель

Все узлы выполняются по порядку, если какой-то из них завершится Success, то выполнение этого контейнера прекращается с результатом Success. Если никакой из них не завершится Success, то контейнер возвращает Failure.

Parallel
(Параллельный)

Выполняет всех своих child'ов "одновременно", в произвольном порядке (in no particular order) (!).

Параметры
Fail - определяет, вернёт ли контейнер Failure, если некоторые или все его child'ы вернут Failure:
- Any - если хотя бы один из них окончится неудачно
- All - если все они окончатся неудачей

Succeed - определяет, вернёт ли контейнер Success, если некоторые или все его child'ы вернут Success:
- Any - если хотя бы один из них окончится удачно
- All - если все они окончатся удачей

Tie Breaker - если оба атрибута Fail и Succeed установлены в Any, определяет, что вернуть контейнеру, если некоторые его child'ы вернули Succeess, а некоторые Failure.

Замечание от авторов.
На каждом такте, пока контейнер не завершил работу, он исполняет ВСЕ свои child'ы (в непредсказуемом для нас порядке, как было сказано выше), даже если окончательный результат работы контейнера на этот момент уже ясен.

Замечание от меня.
"Произвольный порядок" выполнения вложенных узлов видимо подразумевает, что внутри одного параллельного контейнера его child'ы не должны пользоваться никакими данными, которые меняют или предоставляют другие child'ы. Мне как программисту это легче всего представить как работу в разных потоках без какой-либо синхронизации по данным. Это, конечно, серьёзное ограничение, ну что ж...

Iterator
(Итератор)

То же самое, как Sequencer, за исключением того, что повторяется указанное в параметре Count число раз.

Возвращает Success, если на всех итерациях все его child'ы вернули Success.
В ином случае - Failure.

Замечание.
На сайте поддержки заявлено, что Count можно указывать в виде выражения, и, как в приличных циклах типа for, его значение вычисляется ПЕРЕД первой итерацией и возможные его изменения в процессе итераций влияния на число итераций не имеют. А когда же новое значение будет использоваться?
"...new value won't be used until the behavior tree finishes and begins executing again."
Не очень ясно, достаточно ли нового выполнения ветки, в которой находится этот итератор, или всё дерево должно пойти выполняться заново. Впрочем, вопрос теоретический, т.к. никакого "выражения", кроме просто числа, занести в поле Count не удалось.

Random
(Случайный выбор)

Из всех своих child'ов выбирает одного случайным образом и его выполняет. Возвращаемый результат контейнера равен результату выполнения этого child'а.

ДЕЙСТВИЯ (Actions)

Animate
(Анимировать)

Проигрывает на объекте ИИ указанную в параметре Animation анимацию, макс. длительность этого указывается в Wait For Second, как она окончится и будет ли повторяться - а параметре Animation Wrap.
Плавность перехода к-из этой анимации в начале и конце определяется параметрами Fade In Time и Fade Out Time.

Failure возвращается только в случае, если произошла какая-то ошибка.

Некоторые ссылки на сайте разработчика ведут в никуда, вероятно, вопрос с некоторыми параметрами ещё решается так или иначе.

Assign
(Присвоить)

Присвоение переменной значения, определяемого выражением. Также можно (или нужно) указать мин. и макс. допустимые значения. Т.е. фактически присвоится clamp(значение выражения, min, max).

Что знаменательно - ВСЕГДА возвращает Success.

Audio
(Аудио (и зачем я это перевожу?))

Параметры
Audio Source - имя GameObject'а, имеющего компонент AudioSource, причём обязательно находящегося в иерархии нашего объекта ИИ.
Delay - задержка перед проигрыванием
Wait Until Done - ждать ли, чтобы проигралось до конца.

Самоочевидно, что AudioSource уже должен иметь указанный медиа-файл для проигрывания, т.к. его имени в параметрах нет.

Если произошла ошибка, возвращает Failure.

Замечание от меня
Не ясно, вернёт или Running в процессе проигрыша, если не стоит чек Wait Until Done:
"Running - if Wait Until Done is enabled the AudioSource is currently playing."

Condition
(Условие)

Возвращает булевский результат вычисления указанного в Expression выражения.
Success: true, !=0 (особо замечу - не "больше нуля", а "не равно нулю", т.е. и отрицательные тоже)
Failure: false, ==0

Custom Action
(Пользовательское действие)

Выполняет пользовательский скрипт, являющийся наследником специального класса Action.
Шаблон можно создать из формы редактирования дерева. В шаблоне надо заполнить четыре функции.
1. Конструктор Как минимум надо задать имя класса.
2. Start Для инициализации. Вызывается один раз до последовательности вызовов Execute
3. Execute Потихоньку делает всю нужную работу. Вызывается множество раз в каждом такте.
4. Stop Вызывается после всей работы, независимо от того, успешный или нет результат. Возможно, также вызывается для принудительного прерывания работы скрипта из вызвавшего его Дерева Поведений.

Возвращаемый результат имеет смысл только для Execute (пока он не закончил, надо возвращать Running, потом - Success или Failure).

Указанный во всех членах параметр Agent - это ссылка на ИИ. Именно он может интересоваться, ощущать, двигаться, смотреть и т.п. Имеет такие члены, как Agent.Avatar, Agent.Kinematic, Agent.MoveTo...

Вообще надо смотреть примеры и документацию, так не расскажешь на одной странице.

В параметре Class указывается имя класса нужного скрипта (того самого наследника от Action).

Debug
(Отладка)

Позволяет записать в лог указанную в Message фразу (не ясно, можно ли в ней использовать выражения, или это должен быть строковый литерал).
Возвращает то, что указано в поле Returns.

Detect
(Обнаружить)

Параметры
Sensor - имя объекта GameObject, имеющего компонент-сенсор, и являющегося child'ом к объекту ИИ (не ясно, может ли это быть сам объект ИИ)
Aspect - имя признака (Decoration), который мы пытаемся обнаружить. Не ясно, можно ли указываеть несколько признаков (например, через запятую)
Variable - если обнаружится GameObject с нужным признаком (Decoration), то ссылка на него будет помещена в переменную с указанным в этом поле именем.

Возвращает Success, если был обнаружен подходящий объект с нужным признаком и ссылка на него была помещена в Variable.
Failure в ином случае.

Mecanim IK
(Управление инверсной кинематикой в стиле Mecanim)

Используется для того, чтобы посмотреть на что-то, указать рукой или поставить туда ногу. Набор параметров зависит от того, какое действие выбрано. Это действие требует параметра Repeat Forever, либо же должно быть помещено в зацикленный контейнер (чтобы, как я понимаю, было время отыграть это движение).

Про возвращаемое значение написано как-то несмело, возможно, неуспех наступит при невозможности отыскать Mecanim Animator у Аватара.

Mecanim Move
(Передвижение в стиле Mecanim)

Довольно хорошо описана в туториалах и демках.

Параметры
Move Target - координата или переменная, полученная перед этим, например, действием Detect, куда надо идти
Look Target - аналогично на что при этом надо смотреть
Move Speed - вроде как скорость, но не всегда этот параметр оказывает действие
Damp Speed - степень "сглаживания" анимаций. Сдаётся мне, что Rain + IKController напрямую двигают объект ИИ, и те анимации, которые перемещают root, этому передвижению только мешают. Собственно для сглаживания этого противоборства параметр и нужен.

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

Возвращает Failure, если невозможно проложить путь к цели, или если цель исчезла (переменная приобрела значение null)

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

Mecanim Parameter
(Параметр Mecanim-машины состояний)

Собственно, можно напрямую послать нужный параметр в машину состояний анимаций Mecanim.

Параметры
Parameter - имя параметра машины состояний
Parameter Type - тип этого параметра (Boolean, Integer, Float, Vector, Quaternion)
Value - значение параметра (можно и в виде выражения, по словам авторов)
Damp Time - задержка, после которой параметр будет применён (не очень ясно зачем она нужна, вероятно опять же для сглаживания переходов анимаций)

Возвращает Failure, если параметр не мог быть применён (скорее всего Mecanim не найден)

Move
(Движение)
То же, что и Mecanim Move, но без Mecanim. Анимация задаётся напрямую.

Timer
Задержка на указанное число секунд

Yeld
Пауза Дерева Поведений на один такт. Для лучшей производительности.
Что-то типа Application.ProcessMessages для оживления экрана? Не ясно. Или чтобы анимации поглаже состыковать...

Всегда возвращает Success.
Аватара пользователя
Alex3D
UNец
 
Сообщения: 12
Зарегистрирован: 15 май 2013, 22:41
  • Сайт

Re: Behavior trees, Task planning, Neural networks

Сообщение Johnson 28 июн 2013, 06:41

Вот решил перевести и прокомментировать элементы Behavior Tree из Rain{Indie}. Замечания и исправления приветствуются.


Спасибо. (3A4OT)
Johnson появился в результате деления на null. Кривокодер-рецидивист. Кусается.
Хорошо, что в больнице хирурги не такие же, как новички на этом форуме. Пришел вытащить гвоздь из руки, а они яйца оттяпали...
ProgrammerNotFoundException on line 0!
Аватара пользователя
Johnson
UNIверсал
 
Сообщения: 447
Зарегистрирован: 09 июн 2013, 16:31
Откуда: Пермь
Skype: Johnson1893
  • Сайт
  • ICQ


Вернуться в Искуственный Интеллект

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4