Структура ігрової одиниці RTS


18

Я хочу, щоб створити безліч різних підрозділів без необхідності програмувати такі речі, як дії moveTo та Attack не один раз

Як я це бачу, є два способи це зробити.

  1. Єдиний загальний клас Unit з прапорами, який вказує, що він може / що не може робити (тоді створюйте екземпляри в статичному масиві та захоплюйте їх при необхідності)
  2. Абстрактний клас одиниць з абстрактними методами для окремих підрозділів (Attack, Harvest, Patrol), які потім потрібно реалізувати в підкласах , навіть якщо пристрій насправді нічого не може зібрати.

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

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

Це навіть правильний підхід до цієї проблеми?
У такій грі, як AoE, кожен підрозділ має, те, що я припускаю, якийсь перелік дій / доручень, я дуже хотів би знати, як досягти чогось подібного до того, де я можу просто кодувати кожну Дію / Замовлення один раз, і потім дайте її всім підрозділам, які потребують зазначеної дії.

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

Відповіді:


25

Загальний підхід полягає у створенні підходу на основі компонентів, коли базовий клас "Unit" просто реалізує основні аспекти, які мають усі спільні підрозділи, тоді як кожен блок має список декількох об'єктів-компонентів, які говорять про те, що він може робити і як це робиться.

Наприклад, танк може мати компоненти Mobile, Destructible, Attacker, нерухома турель тільки Destructible, Attackerі комбайн Mobile, Destructible, Harvester. Потім ці класи включатимуть весь код, необхідний для реалізації цих способів поведінки. Взаємодія між компонентами (a Attackerможе пошкодити лише те, що є Destructible) можна реалізувати, якщо компонент перевірить, чи має інший підрозділ потрібний компонент, а потім безпосередньо взаємодіє з цим компонентом.

Перевага перед класичним успадкуванням класу полягає в тому, що ви можете легко поєднувати здібності. Наприклад, коли ви хочете мати комбайн, який також може атакувати, перевозити піхоту і літати, вам просто потрібно додати необхідні компоненти. Ви також можете легко додавати та видаляти нові функції у вигляді нових компонентів без необхідності роздувати базовий клас Unit.

Unity підтримує вас у такій архітектурі, адже весь двигун вже є компонентним. Тож такі ігрові логічні компоненти, як вони, можна додавати у вигляді скриптів.


Тож у єдності я б тоді відключив та включив компоненти за потребою ?.
Даніель Холст

@DanielHolst Ні, ви додасте та видалите їх за потребою. Це можна зробити в редакторі Unity або за допомогою скриптів за допомогою gameObject.AddComponentта gameObject.RemoveComponent.
Філіп

ну гаразд, але скажіть для дії / наказу "moveTo". як би підрозділ знав, коли виконується замовлення ?, і як я буду в черзі на замовлення?
Даніель Холст

2
@DanielHolst Я думаю, що ти щось неправильно зрозумів. В Movingозначає компонент «цей блок , як правило , здатний до руху». Компонент постійно приєднаний до нього, незалежно від того, рухається одиниця чи ні. Це не означає, що він рухається зараз . Хоча ви могли б також зробити це таким чином, додаючи MoveOrderкомпонент до нього і з самим цим компонентом видалити з блоку , коли замовлення виконано або скасований.
Філіп

1
@DanielHolst Тепер ви рухаєтесь у бік AI, що є цілком іншим банком глистів. Можливим підходом може бути наявність бібліотеки компонентів AIScript, які або припускають, що певні компоненти присутні, або змінюють свою поведінку залежно від того, які компоненти в апараті є. Але це справді занадто складна тема, яку можна вирішити в коментарі.
Філіп

4

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


це було б надзвичайно важко здійснити?
Даніель Холст

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

1
@DanielHolst Я помічаю, що у вашому запитанні є Unityпрапор. Єдність вже має вбудовану компонентну систему і сильно підтримує склад над успадкуванням . Одним з простих методів було б створити MonoBehaviourтип для кожного з типів вашої дії, а потім приєднати до кожного типу одиниць збірки дії, які він може виконувати (налаштування екземплярів дії з деталями для типу типу, як значення шкоди та витрати). Це забезпечує збереження даних про створення пристрою, тому ви можете легко створити багато типових одиниць.
DMGregory

@DanielHolst Це залежить від вашого визначення "надзвичайно важкого". Моя відповідь детальніше описує, як це можна було б реалізувати.
Філіп
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.