Я начинаю внедрять ИИ игрока и врага в игру, но меня смущает, как лучше всего реализовать это в игровой архитектуре на основе компонентов.
Скажем, у меня есть следующий персонаж игрока, который может стоять, бегать и размахивать мечом. Игрок может перейти в состояние размахивающего меча как из стационарного, так и из бегового состояния, но затем размах должен быть завершен, прежде чем игрок сможет возобновить стояние или бег вокруг. Во время свинга игрок не может ходить.
На мой взгляд, у меня есть два подхода к реализации:
- Создайте один AI-компонент, содержащий всю логику игрока (либо отделенную от реального компонента, либо встроенную как PlayerAIComponent). Я могу легко, как применить ограничения состояния без создания связи между отдельными компонентами, составляющими объект игрока. Однако AI-компонент не может быть разбит. Если у меня есть, например, враг, который может только стоять и ходить или только ходить и время от времени размахивать мечом, я должен создать новые AI-компоненты.
- Разбейте поведение на компоненты, каждый из которых идентифицирует определенное состояние. Затем я получаю StandComponent, WalkComponent и SwingComponent. Чтобы обеспечить соблюдение правил перехода, я должен соединить каждый компонент. SwingComponent должен отключить StandComponent и WalkComponent на время колебания. Когда у меня есть враг, который только стоит, время от времени размахивая мечом, я должен убедиться, что SwingComponent отключает WalkComponent, только если он присутствует. Хотя это позволяет лучше смешивать и сопоставлять компоненты, это может привести к кошмару удобства сопровождения, так как каждый раз, когда добавляется зависимость, существующие компоненты должны обновляться, чтобы соответствовать новым требованиям, предъявляемым к персонажу в зависимости.
Идеальной ситуацией может быть то, что дизайнер может создавать новых врагов / игроков, перетаскивая компоненты в контейнер, не затрагивая ни одной строки кода движка или скрипта. Хотя я не уверен, что можно избежать написания сценариев, я хочу сделать его как можно более простым.
Подводя итоги: следует ли мне разбить всю логику ИИ на один компонент или разбить каждое логическое состояние на отдельные компоненты, чтобы легче создавать варианты сущностей?
редактировать : я подозреваю, что есть некоторая путаница о том, что я имел в виду с первой и второй ситуацией. Я попытался объяснить это на диаграмме ниже.
Обратите внимание на отношения между отдельными состояниями и объектом. В первой ситуации компонент ИИ предварительно создается перед тем, как помещаться в сущность. Дизайнер может выбирать только из отдельного набора компонентов AIC, предоставляемых программистом. Вторая ситуация имеет различные состояния на том же уровне, что и другие компоненты. Дизайнер теперь может создавать сущности с уникальным ИИ без вмешательства программиста.
Вопрос в том, являются ли это единственными двумя вариантами структурирования ИИ в компонентной сущности, и если да, то что даст максимальную гибкость?
источник
Ответы:
Если вы намереваетесь иметь больше возможных врагов или игроков, которых вы не можете себе представить, то вам обязательно нужно их разбить. То, что вы описываете в своем втором пункте, является в основном моделью состояния .
Я думаю, что согласен с Грегори, что у вас не должно быть отдельных компонентов состояния стенда и ходьбы. Это просто компонент движения со скоростью 0. С другой стороны, если у вас есть объекты, которые не могут двигаться, вы должны либо разделить его, либо просто поместить какое-то логическое ограничение в состояние движения, которое предотвращает ненулевую скорость ,
Для игрока я не думаю, что это должно быть полностью отделено. Он по-прежнему может использовать все остальные компоненты с добавлением компонента ввода. Этот компонент управляет переходами между состояниями, в то время как у врага он контролируется ИИ по умолчанию или, если хотите, различными подклассами ИИ, из которых могут выбирать ваши вражеские дизайнеры.
редактировать: фактически, для ваших постоянных врагов, вместо того, чтобы ограничивать компонент движения, просто дайте им постоянный компонент ИИ, который никогда не решит их перемещать.
источник
По крайней мере, я бы оставил AI игрока (или то, что я бы назвал Player Controller) своим собственным компонентом. В большинстве игр игрок принципиально отличается от неигровых персонажей, которых нельзя обобщать между собой, кроме как в основах, таких как очки жизни.
Для NPC я вижу StandComponent и WalkComponent как аспекты одного и того же. Вы когда-нибудь собираетесь иметь WalkComponent без StandComponent? Я сомневаюсь в этом. Аналогично, RunComponent будет просто WalkComponent с более высокой скоростью и различными анимациями. Я вижу ценность в наличии NPCMovementComponent и отдельного NPCSwordFighterComponent, но даже для меня это похоже на чрезмерную работу.
источник
Сначала я создавал компонент State, а затем создавал конечный автомат для обработки переходов. Сделайте его достаточно общим, чтобы вы могли использовать его для своих игроков и своего ИИ. Это гарантирует, что ИИ будет играть по тем же правилам, и вам не придется менять свою логику, когда вы изменяете работу состояний игрока по сравнению с состояниями ИИ.
Конечный автомат C ++
Выше приведен конкретный пример конечного автомата в c ++, который может использоваться как игроками, так и ИИ.
источник
То, что вы хотите, это компонент, управляющий движением персонажей (игрока и NPC). Компонент AI или компонент игрока отправит команды этому компоненту движения и проверит, можно ли инициировать действие. Это будет заключать ваши ограничения движения в один компонент. Ваш код AI и код игрока не должны знать, как исполняется свинг-меч. ИИ будет иметь внутренние состояния, например: холостой, атакующий, бегущий.
источник