Шукаєте деяку інформацію про дизайн програмування для атак та типів атаки в грі


14

Отже, я починаю вводити атаку на наш 2D-простір RTS (Це в Unity, тому він керується компонентами). Спочатку це було так само просто, як "ворог у дальності, завданий збиток". Однак буде декілька "типів" зброї / атак, пов'язаних з їх конкретним кораблем або структурою. Так само, як і інші фактори, пов'язані з попередньою сильною шкодою, наприклад типом збитків, а можливо, інерцією в майбутньому.

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

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


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

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

Якщо це недостатньо зрозуміло, дайте мені знати.

Редагувати: Чудові відповіді, дякую.

Розширене запитання:

Відповіді, схоже, відрізняються від "кожен об'єкт може мати свій власний скрипт атаки" до "Майте типи атак як власні сценарії та призначте їх кожному об'єкту для більш багаторазового використання". Скажімо, я маю напад "бластер", він стріляє червоним снарядом з певною швидкістю. Пошкодження, швидкість вистрілу та розмір снаряда залежать від того, який підпалює. Чи краще просто скласти скрипт атаки для цього блоку або спробувати змінити "атаку бластера", щоб відповідати цілі кожного підрозділу, який хоче його використовувати?


1
Для загальних ігрових ідей програмування я хочу посилатися на повну специфіку RPG FFV - gamefaqs.com/snes/588331-final-fantasy-v/faqs/30040
Code Whisperer

Відповіді:


12

Ну, я, чесно кажучи, не фахівець у цьому, але ... Я думаю, це залежить від того, наскільки складними та різноманітними ви вважаєте, що напади стануть. Оскільки це RTS, я здогадуюсь, у вас може бути 10-50 або більше різних підрозділів або структур із власними типами атак.

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

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

Варіант 3: Те, що ви, мабуть, не повинні робити, - це певні угруповання скриптів для спільного використання одиниць; це, швидше за все, збиває з вас збентеження і стане безладдям, якщо код, необхідний для атаки, міститься в 10 різних сценаріях.

Тут я намалював вам картину.

введіть тут опис зображення


2
Дуже дякую за відповідь. Я чомусь починав схилятися до варіанту 3, і мені важко було знайти спосіб виправдати це. Я, мабуть, пройду другий маршрут, кожен блок отримує власний власний скрипт атаки із загальним кодом, який використовується загальним кодом, атакованим як компонент кожного блоку / будівлі. Я не впевнений, куди я їхав із потягом думки, який привів мене до варіанту 3, дякую. Я залишаю це відкритим, поки не встану в АМ, якщо є інші плакати, які хочуть прозвучати.
Дуглас Гаскелл

Немає проблем, це не остаточна відповідь, але сподіваюся, що це допоможе.
Мир

1
Ви можете гібридизувати 1 і 2, розмістивши подібні атаки в одному великому сценарії та відокремивши різні атаки
храповик виродка

4
Я здивований, що №3 рекомендується проти? Чи не вся суть модульних / загальних класів, щоб кожен одиниця не мала визначати власний тип? Якщо гра - це RTS, а пошкодження Siege (як правило, "дальність дії") - це тип пошкодження, ви хочете визначити її один раз і мати декілька підрозділів у стилі артилерії, які посилаються на неї під час виконання їхніх обчислень, так що якщо обробка пошкодження коли-небудь потрібно було понервувати (врівноважити), вам доведеться оновити лише один клас?
HC_

1
"Here, I drew you a picture."нагадав мені про це
FreeAsInBeer

4

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

Ваш проблемний простір такий:

  • Існує кілька способів атаки противника в грі в цілому.
  • Кожен корабель, споруда тощо може мати кілька способів атаки (кожен визначається певним чином)
  • Кожна атака може мати свої власні ефекти.
  • Напад повинен враховувати деякі фактори (наприклад, інертність або броня, наприклад), які присутні в цілі та користувачеві.

Я б структурував рішення таким чином:

  • Напад має ідентифікатор - це може бути рядок.
  • Суб'єкт господарювання "знає", що може використовувати атаку (на основі ідентифікатора атаки).
  • Коли атака використовується сутністю, до сцени додається відповідний компонент відображення.
  • Ви маєте певну логіку, яка знає про ціль нападу, нападника та атаку, яка використовується - ця логіка повинна вирішити, скільки шкоди ви завдаєте (і мати доступ до інерції чи будь-якої з обох сутностей).

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

// components
var bulletStrength = { strength: 50 };
var inertia = { inertia: 100 };
var target = { entityId: 0 };
var bullets = {};
var entity = entityManager.create([bulletStrength, inertia, target, bullets]);

var bulletSystem = function() {
  this.update = function(deltaTime, entityId) {
    var bulletStrength = this.getComponentForEntity('bulletStrength', entityId);
    var targetComponent = this.getComponentForEntity('target', entityId);
    // you may instead elect to have the target object contain properties for the target, rather than expose the entity id
    var target = this.getComponentForEntity('inertia', targetComponent.entityId);

    // do some calculations based on the target and the bullet strength to determine what damage to deal
    target.health -= ....;
  }
};

register(bulletSystem).for(entities.with(['bullets']));

Вибачте, що ця відповідь трохи "водянистий". У мене лише півгодинна перерва на обід і важко придумати щось, не знаючи повністю про Єдність :(


3

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

Розгорнута відповідь
Ось як я підходив до нападу бластера з таким підходом . Я дозволю іншим відповісти за себе.

Я б змусив своїх підрозділів реалізувати інтерфейс або клас IAttacker з базовою статистикою / методами атаки. Коли IAttacker атакує IDamageable, він створює свою специфічну атаку, передаючи себе та свою ціль (IAttacker і IDamageable, або, можливо, колекцію ідентифікаційних матеріалів). Attack захоплює необхідні статистичні дані від IAttacker (щоб уникнути змін під час оновлення чи чогось подібного - ми не хочемо, щоб Attack змінював свою статистику після того, як вона вже була запущена), і якщо вона потребує спеціалізованої статистики, кидає IAttacker на потрібний тип (наприклад, IBlasterAttacker) і отримує спеціалізовану статистику таким чином.

Дотримуючись такого підходу, BlasterAttacker просто повинен створити BlasterAttack, а BlasterAttack піклується про інше. Ви можете підкласировать BlasterAttack або створити окремі FastBlasterAttacker, MegaBlasterAttacker, SniperBlasterAttacker тощо. Код атаки для кожного однаковий (і, можливо, успадкований від BlasterAttack): Створіть BlasterAttack та передайте себе та мою ціль (и) в. BlasterAttack деталі. .


По суті, пристрій успадковує інтерфейс IAttacker (у мене це вже є), і для "ворога" є інтерфейс, що змінюється "Ідентифікатор" (мати це також). Коли нападник атакує, викликається BlasterAttack (або похідний клас). Ця "атака" отримає потрібні дані з IAttacker і застосує їх до Ідентифікатора, коли снаряд потрапить? Чи містить сам снаряд клас BlasterAttack, так що після його запуску він більше не впливає на зміни IAttacker, і може застосувати його пошкодження / наслідки для Ідентифікатора, лише якщо його снаряд насправді вражає.
Дуглас Гаскелл

Коли ви кажете "називається BlasterAttack (або похідний клас)", я б сказав, що створено BlasterAttack. Цей новостворений екземпляр BlasterAttack є пучок (або кулі або промінь або будь-який інший ), так що це снаряд. BlasterAttack копіює всі необхідні статистичні дані з об'єктів IAttacker та IDamageable: позицій, статистики зловмисників тощо. Потім BlasterAttack відстежує власну позицію і, якщо застосовно, завдає шкоди при "контакті". Вам потрібно буде розібратися, що робити, якщо він пропустить або досягне місця призначення (стара позиція цілі). Спалити землю? Зникнути? Твій дзвінок.
ricksmt

Для атаки в зоні дії, можливо, ви хочете отримати доступ до глобальної колекції (ворожих) підрозділів, оскільки хто знаходиться в зоні дії, а хто знаходиться поза зоною дії, може змінюватися між вогнем і ударом. Звичайно, подібний аргумент можна зробити і для BlasterAttack: ви пропускаєте свою початкову ціль, але вдаряєте хлопця за собою. Моє єдине занепокоєння полягає в тому, що у вас може бути багато італій, що повторюються через багато ворогів, які намагаються з'ясувати, чи потрапили вони. Це стурбованість роботи.
ricksmt

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

Без проблем. Радий, що міг. Забули, що Unity полегшує все це зіткнення.
ricksmt
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.