Blog vadakuma вогнепальну зброю в udk

вступ

Сьогодні ми будемо говорити про базові знання та налаштування стосуються створення зброї.
UDN Weapon System Technical Guide (яку я називаю WSTG) дає нам деякі поняття: як працює механізм перемикання зброї, як працює блок відповідає за режим вогню (навіть по мережі), в чому різниця між функціями в класі Weapon і його дочірніх класів.

Сторінка Setting Up Weapons розповідає нам як змоделювати і імпортувати зброю, і який код треба написати. для UTWeapons.

І все ж, після прочитання всього цього, ми до сих пір не знаємо деякі речі:

• Як додати зброю в стандартний інвентар.
• Встановити різні види пострілів для зброї.
• Які функції необхідно переписати щоб управляти деякими характеристиками зброї.
• Як працює система шкоди.

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

Вихідна точка: InventoryManager

Примітка. InventoryManager зав'язаний на Pawn. а не на PlayerController.

Ще одна важлива річ яку ми повинні знати про клас InventoryManager. це те що він просто відстежує статус поточного зброї: значення PendingFire. про який ми читали в WSTG. Хоча цей масив ініціалізується не в InventoryManager. Іншими словами, база InventoryManager не дозволяє стріляти за допомогою нього (наробите кумедних помилок, якщо спробуєте так зробити) .По замовчуванням для класу UDKPawn інвентарем заправляє саме InventoryManager. тому нам треба створити підклас від останнього, для того щоб навчитися стріляти.


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

Пр. перекладача. PendingFire - масив, що містить кількість та статус альтернативних режимів пострілу одного і того ж зброї. Наприклад, PendingFire (0) = 0 означає що зброя не стріляє, PendingFire (0) = 1 - зброя в режимі огня.По замовчуванням, Режим пострілу (Fire mode) 0 активується по ЛФМ, а Режим пострілу (Fire mode) 1 , по ПКМ.

Як я зазначив раніше, InventoryManager пов'язаний з Pawn. тому нам необхідно сказати нашому pawn, щоб він використовував наш власний InventoryManager:

Ліпимо зброю (скрипти)

Ми можемо створити власну зброю двома шляхами: по-перше ми можемо спочатку написати поведінка зброї (ефекти пострілу, снаряди) і лише потім зробити для нього зовнішній вигляд. Приклад physics gun якраз демонструє, що зброя не особливо потребує моделі, для того щоб повноцінно функціонувати. Для прикладу створимо paintball gun.


Крок 0: кілька підказок про налаштування зброї


• FiringStatesArray (array): задається через ім'я. Яке говорить про статус зброї в руках і про режим вогню. За замовчуванням не використовується. Ви можете призначити будь-яке значення, яке побажаєте, якщо не хочете заново винаходити велосипед. (Пр. Перекладача: цього параметра вже немає в скриптах)

• WeaponFireType (array): задається через EWeaponFireType. Каже, до якого типу належить зброя. Ми доберемося до нього трохи пізніше.

• WeaponProjectiles (array). задається через підклас снарядів. Якщо відповідний режим вогню встановлюється на постріли певними снарядами, ви повинні знати який клас снарядів повинен викликатися для даного зброї.

• FireInterval (array): задається через float. Вказує скільки часу займає постріл в даному режимі вогню. Іншими словами - темп стрільби.

• Spread (array): задає похибка в напрямку пострілу (як би "розкид"). Інакше, все кулі (снаряди) летітимуть завжди точно в ціль. Що ні правдоподібно.

• WeaponRange. задається через a float. Визначає максимальну дальність пострілу, шкоди, час життя снаряда. Зверніть увагу, що це значення є загальним для всіх режимів вогню.


Крок 0.5. додаємо наша зброя в інвентар

Ми зробимо це так, що б легко було простежити за суттю реалізації коду.
Коли player перезапускается (тобто початок гри, рестарт гри, воскресіння гравця), клас Pawn створюється з GameInfo і прикріплюється до PlayerController. і GameInfo викликає функцію AddDefaultInventory. приймаючи новий Pawn як параметр.
П про замовчуванням не робиться нічого крім виклику функції AddDefaultInventory в класі Pawn. І це добре з багатьох причин. Проте, є базовий клас гри. І швидше за все ви будете мати ще підклас від класу Pawn (для персонажа). AddDefaultInventory з класу GameInfo можна переписати, якщо у вас є якісь загальні параметри, настройки для всіх класів (наприклад, для ножа).

Отже, в нашому власному Pawn класі, переписуємо функцію AddDefaultInventory ось так.

Все просто. Функція має і другий необов'язковий параметр, якщо його значення TRUE, то буде запобігати негайна екіпірування зброї. Тепер, якщо ми запустимо гру, ми нічого не побачимо, з огляду на те що у зброї немає власного заважав. І все ж, якщо написати в консолі чарівну команду "showdebug weapon". ми побачимо наступне в верхньому лівому кутку екрана:

Blog vadakuma вогнепальну зброю в udk

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

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

Коли відведений час закінчиться, спрацює RefireCheckTimer. Він перевіряє дві речі:

1. Чи була команда перестати стріляти зброю. Якщо так, то відбувається виконання команди.
2. Якщо команди перестати зброї не було, відбувається запит функції ShouldRefire. Якщо повертається TRUE, відразу викликається FireAmmunition без виходу з блоку.


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


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


Функція ShouldRefire перевіряє чи є боєприпаси у зброї (функція HasAmmo за замовчуванням завжди повертає TRUE), якщо вам ще хочеться постріляти. (Функція StillFiring за замовчуванням повертає значення функції PendingFire).
WSTG показує нам тіло функції FireAmmunition (від старої версії UTWeapon. Хоча всі основні ідеї збереглися і там). Спершу використовуються боєприпаси, (по замовчування нічого не відбувається), а потім визначається режим вогню, після чого, відповідно до режиму, викликаються різні функції.
Іншими словами, режим вогню встановлений на зброю, більш-менш, говорить з якими функціями нам слід попрацювати:

EWFT_InstantHit. InstantFire () Тимчасовий вогонь
EWFT_Projectile. ProjectileFire () Вогонь снарядами
EWFT_Custom. CustomFire ​​() Щось саморобний

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

Швидкоплинний вогонь. (Instant Fire)

Все це нам дає наступний результат:

Крім того, якщо ви помітили, за замовчуванням вийшло зброя знаходиться в режимі "full auto" (автоматичне). А що якщо необхідний режим одиночного пострілу (тобто потрібно натискати на кнопку каждийраз коли треба вистрілити)?
Добре, нехай це буде вашим домашнім завданням! Пара підказок:

- PendingFire обнуляється лише коли відбувається виклик StopFire
- За замовчуванням StillFiring передбачає що у PendingFire єсть значення TRUE, тому зброя повинна продовжити стріляти.


Крок 2: Відображення зброї

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

Я використовую меш Link Gun д ля прикладу. Взагалі використовуються різні види моделі одного і того ж зброї в залежності від виду камери в грі. Якщо ви подивіться в AnimSet Editor на зброю, то помітите, що воно зміщене в сторону. Найімовірніше це попереднє зміщення, для адекватного позиціонування зброї.

Вид зброї з камерою від першої особи. (First Person perspective)

Клас UDKWeapon має в собі функцію SetPosition. вона викликається при кожній наступній промальовуванні кадру. За умовчанням вона нічого не робить, але її можна переписати так щоб вона помістила модель зброї в правильне місце, за образом і подобою як діє та ж функція, тільки в UTPawn. Кілька грубувате рішення, але зі своїм завданням справляється.


Якщо ви читали мої Тутори про камери, то можливо зрозуміли, що саме я тут сделал.По деяких причин, виклики SetHidden (false) і SetBase необхідні. Ось що виходить в результаті.

Вид зброї з камерою від третьої особи. (Third Person Perspective)

А ось це набагато простіше. І не вимагає знань просторової геометрії. ) Все що нам треба, так це причепити модель зброї до відповідного сокету.
Що б зробити це, потрібно використовувати функцію AttacWeaponTo з класу UDKWeapon. яка приєднає SkeletalMeshComponent до відповідного сокету. Але справа в тому, що за замовчуванням, ця функція не викликається (напевно тому, що не знає куди приєднувати зброю). Швидкий огляд класу UTWeapon показав нам, що все це повинно робитися в TimeWeaponEquipping. що в загальному, має сенс. Перепишемо ці функції:


Чи не правда все просто. А ось результат наших старань:

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

Схожі статті