Як реалізувати поведінку в компонентній архітектурі ігор?


21

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

Скажіть, у мене є такий гравець, який може бути нерухомим, бігаючи і розмахуючи мечем. Гравець може перейти до стану гойдалки мечем як із стаціонарного, так і з бігового стану, але тоді гойдання має бути завершено, перш ніж гравець може відновити стоячи або бігати. Під час гойдалки гравець не може ходити.

Як я бачу, у мене є два підходи до реалізації:

  • Створіть єдиний AI-компонент, що містить всю логіку програвача (або від'єднаний від фактичного компонента, або вбудований як PlayerAIComponent). Я легко можу виконати державні обмеження, не створюючи зв'язку між окремими компонентами, що складають сутність гравця. Однак AI-компонент не може бути розбитий. Якщо у мене, наприклад, є ворог, який може лише стояти і ходити, або лише ходити навколо і час від часу розмахувати мечем, я повинен створити нові AI-компоненти.
  • Розбийте поведінку на компоненти, кожен з яких визначає конкретний стан. Потім я отримую StandComponent, WalkComponent і SwingComponent. Щоб застосувати правила переходу, я повинен з'єднати кожен компонент. SwingComponent повинен відключити StandComponent і WalkComponent протягом тривалості гойдалки. Коли у мене є ворог, який стоїть навколо, періодично розмахуючи мечем, я повинен переконатися, що SwingComponent відключає WalkComponent лише у разі його наявності. Хоча це дозволяє покращити сумішування та суміщення компонентів, це може призвести до кошмару технічного обслуговування, оскільки кожен раз, коли залежність додається, існуючі компоненти повинні бути оновлені, щоб добре грати з новими вимогами, які залежать від персонажа.

Ідеальною ситуацією було б те, щоб дизайнер міг створювати нових ворогів / плеєрів, перетягуючи компоненти в контейнер, не торкаючись жодного рядка двигуна чи сценарію. Хоча я не впевнений, що кодування скриптів можна уникнути, я хочу його максимально просто.

Підсумовуючи це все: Чи слід розподіляти всю логіку AI на один компонент або розбивати кожен логічний стан на окремі компоненти, щоб легше створювати варіанти сутності?

редагувати : Я підозрюю, що існує деяка плутанина щодо того, що я мав на увазі під першою та другою ситуацією. Я намагався пояснити це на схемі нижче.

Компонентна схема

Зверніть увагу на зв’язок між окремими державами та утворенням. У першій ситуації компонент AI попередньо будується перед тим, як вводити в сутність. Дизайнер може вибрати лише окремий набір AIComponents, який надає програміст. Друга ситуація має різні стани на тому ж рівні, що й інші компоненти. Тепер дизайнер може створити об'єкт з унікальним AI без втручання програміста.

Питання полягає в тому, чи це єдині два варіанти структурування AI в компоненті, що базується на компонентах, і якщо так, то що дасть максимальну гнучкість?


Я думаю, що хороша відповідь буде залежати від того, де ви хочете застосувати винятковість дій. Якщо ви хочете, щоб це було в самих об'єктах, дизайн буде значно відрізнятися порівняно з, наприклад, примусовим його через інтерфейс перетягування (цей стан вже має рух руху, тому він не може мати іншого, цей контейнер переходу стану вже містить кінцевий стан, який базується на часі тощо, тощо).
Джеймс

2 не є життєздатним варіантом.
Койот

Відповіді:


6

Якщо ви маєте намір мати більше можливих ворогів чи гравців, яких ви зараз не уявляєте, то вам обов'язково слід розбити це. Те, що ви описуєте у своєму другому пункті, - це в основному схема стану .

Я думаю, що я погоджуюся з Григорієм, що у вас не повинно бути окремих компонентів для підставки та прогулянок. Це просто компонент руху зі швидкістю 0. З іншого боку, якщо у вас є об'єкти, які не можуть рухатись, вам або потрібно розділити їх, або просто поставити якесь булеве обмеження у стані руху, яке не дозволяє мати нульову швидкість .

Для гравця я не думаю, що це потрібно зовсім окремо. Він все ще може використовувати всі інші компоненти, додаючи вхідний компонент. Цей компонент керує переходами між станами, тоді як у ворога він управляється за допомогою типового AI або, якщо ви хочете, різних підкласів AI, які можуть обрати ваші ворожі дизайнери.

редагувати: насправді, для ваших нерухомих ворогів, а не обмежуючи компонент руху, просто надайте їм стаціонарний компонент AI, який ніколи не вирішить їх переміщувати.


Чи не означає, що модель держави передбачає першу ситуацію? Це призводить до того, що один AIComponent реалізує державну машину, що містить різні об'єкти стану. Що я мав на увазі під другим варіантом, це те, що WalkComponent і SwingComponent є одного типу, як, скажімо, RenderComponent і PhysicsComponent.
привид

@ghostonline Що стосується ідеї, начебто. У реалізації не дуже. AIComponent буде окремим, як на другій схемі. Він не міститиме інших компонентів. Більш важливим питанням для вашої другої ситуації є те, якщо дизайнер просто вибирає компоненти без програміста, як Entity знає, коли потрібно змінити стан? Різні стани мають на увазі різні переходи стану - комусь все одно потрібно вказати їх.
Тессерекс

Ви маєте на увазі додавання AIComponent до сутності на схемі 2, яка буде керувати Stand / Walk / Swing-Component? Моя ідея полягала в тому, що компоненти надсилають блок або сигнали активації за певних умов. Наприклад, SwingComponent буде випромінювати загальні сигнали, наприклад, сигнал "linked_feet" при запуску і "release_feet" при закінченні гойдалки. На основі цих сигналів WalkComponent відключить і ввімкне себе. Оскільки "переходи стану" інкапсульовані в самих компонентах, дизайнеру не знадобиться програміст, який з'єднує компоненти разом.
привид

@ghostonline Це чудово працює для речей, у яких є фіксовані правила, наприклад "не можна ходити, коли гойдатися", але як бути з переходами між стійкою та ходьбою? Якщо стоїть під контролем, як він знатиме спробувати ходити? Логіка, що стоїть, може захотіти вибрати ходу або гойдалку, на яку впливає повна відсутність здатності ходити - у такому випадку вона завжди повинна гойдатися. Але я думаю, що ти на правильному шляху.
Тессерекс

2

Я хоч би зберігав AI Player Player (або те, що я б назвав Player Controller), як власний компонент. У більшості ігор гравець принципово відрізняється від NPC, що ви не можете узагальнити один на інший, за винятком таких основ, як точки удару.

Для NPC я бачу StandComponent і WalkComponent як аспекти одного і того ж. Ви коли-небудь будете мати WalkComponent без StandComponent? Я сумніваюся в цьому. Так само RunComponent був би просто WalkComponent з більшою швидкістю та різними анімаціями. Я бачу цінність у наявності NPCMovementComponent та окремого NPCSwordFighterComponent, але навіть мені здається, що це переоцінка для мене.


Я б так не розділяв рух NPC та рух гравця. Рухові дії, які керують анімацією та фізикою, безумовно, можна поділити; це те, що вибирає дії чи переходи, які відрізняються (гравець бере вхід, а AI - AI). Я погоджуюся, що у вас буде PlayerController, але у вас також буде AIController, обидва вони можуть використовувати компоненти Movement / Swing Components, щоб отримати фактичну роботу з анімацією / фізикою.
домашня мова

Правда. Я припускаю, що всі рухомі об'єкти мають PhysicsComponent або MovementComponent, який обробляє їх рух, і що PlayerController і AIController будуть використовувати це для управління рухом. Рух, безумовно, повинен бути окремим компонентом, оскільки там можуть рухатися речі, які не мають AI або мають найпростіший можливий ШІ (тупі об’єкти фізики, як ящики або сміття).
Григорій Евері-Вейр

2

Спершу я склав би компонент State, а потім створив би державну машину для обробки переходів. Зробіть це загальним, щоб ви могли використовувати це для своїх гравців та своїх AI. Це переконається, що AI грає за тими ж правилами, і що вам не доведеться змінювати свою логіку, коли ви змінюєте, як працюють штати гравців, порівняно зі станами AI.

Кінцева державна машина C ++

У вищесказаному є конкретний приклад стану машини в c ++, який можуть використовуватись і гравці, і AI.


1

Те, що ви хочете, - це компонент, що управляє рухом персонажів (програвач та NPC). Компонент AI або компонент програвача відправить команди на цей компонент руху, і він перевірить, чи можна ініціювати дію. Це дозволить обмежити ваші обмеження руху в один компонент. Ваш код AI та код гравця не повинні знати, як виконується гойдальний меч. ШІ матиме внутрішні стани, наприклад, бездіяльність, атака, втеча.


1
TYPO: "Це отримає ..." що з компонента AI?
Щеня
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.