AI
Last updated
Last updated
Система ИИ строится на концепции “finite state machine” (версия не на стеке). Есть состояния и переходы между ними (как в аниматоре). Для того, чтобы создать компонент ИИ для сущности, надо создать объект в боте, в этот объект поместить компоненты “StateMachine”, “StateData” (лучше создать свой тип даты для разных ботов, унаследовав класс) и все типы состояний “State”, используемые в ИИ. Состояния создаются наследованием от класса “State<T>”. В качестве “T” надо указать свой “StateDate” тип. В компоненте “StateMachine” надо построить граф со стейтами и переходами между ними. Стейты следует называть так же как и их классы (они привязываются по имени). “StateData” используется для хранения внешних ссылок и как интерфейс взаимодействия с внешними объектами.
В состоянии реализуется логика поведения и переходов. Для этого есть виртуальные методы “OnEnter”, “OnUpdate”, “OnExit”, которые вызываются при активации состояния, в апдейте если активно, и при выходе из него соответственно.
Чтобы перейти в другое состояние, надо вызвать метод “ChangeState” и в дженерике указать тип нового состояния. Хотя переходы между состояниями можно делать и в “OnUpdate” (или в “OnEnter”) при каком-либо условии, всё же рекомендуется это делать с помощью подписания на эвенты в “Start” методе.
Также в обновлении был добавлен виртуальный метод “RareUpdate”, который вызывается каждый 10 вызов апдейта. Свою задержку вызова можно установить в Awake через вызов метода “SetRareUpdateSkipFrames”
Чтобы избежать срабатывание кода в эвенте когда текущее состояние другое (если подписался в “Start”), надо в методе поставить в начале условие: “if (!IsCurrent()) reutrn;” “IsCurrent” возвращает является ли это состояние активным в данный момент
Данные об сущности рекомендуется хранить в вашей реализации “StateData”, а получить их можно через поле родителя всех стейтов “data” (например “data.Agent” получает NavMeshAgent, указанный в сцене в компоненте “StateData”). В качестве “Main” в “StateData” надо указывать ссылку на родительский (самый-самый) объект бота. Также НЕ рекомендуется менять состояния напрямую извне, иначе потом будет непонятно почему данное состояние поменялось в данный момент. Поэтому если хотите поменять состояние под влиянием чего-либо, эти данные надо передать сначала в реализацию “StateData”, а потом уже подписавшись (ValueObservable) из состояния на изменение этого значения думать делать переход или нет.