06 — Спорядження¶
🇬🇧 English | 🇺🇦 Українська
Носіння предметів у названих слотах: зброя в руці, шолом на голові, каблучка на пальці.
Слоти — це теги, а не перелічення¶
Які слоти існують, задається на компоненті в полі AvailableSlots. Плагін ніколи
не вгадує, як влаштоване тіло вашого персонажа.
Середньовічний RPG: Weapon.Main, Weapon.Offhand, Armor.Head, Armor.Chest, Accessory.Ring ×2
Мех-симулятор: Arm.Left, Arm.Right, Torso, Legs, Reactor
Картярська гра: (компонент не потрібен зовсім)
Предмет заявляє, куди він проситься, через свій фрагмент Equippable. Вдягнути його
можна лише туди, де такий слот справді є.
Це найчастіша причина «чому не вдягається»: предмет просить слот, якого немає в
AvailableSlotsцього персонажа. Інспектор показує обидва боки — 13 — Відлагодження.
Налаштування компонента¶
Add Component → Equipment.
| Поле | Опис |
|---|---|
AvailableSlots |
схема тіла: які слоти взагалі існують |
LinkedInventory |
рюкзак, з якого беруть і куди повертають |
bAutoLinkInventoryOnSameActor |
знайти інвентар на тому ж акторі (типово увімкнено) |
LinkedInventory можна не чіпати: компонент сам знайде інвентар на своєму акторі.
Пошук лінивий — він спрацює навіть тоді, коли інвентар додали пізніше.
Залишити зв'язок порожнім доречно, коли спорядження живе саме по собі: зброя NPC, яку не можна забрати, або манекен для попереднього перегляду.
Вдягання й зняття¶
Найзручніша форма — гравець обирає предмет, а не місце:
Equipment->TryEquipFromInventorySlot(InventorySlotIndex);
Предмет сам знає, у який слот він проситься. Це виклик за пунктом «Вдягнути» в контекстному меню.
Явна форма, коли слот відомий:
Equipment->TryEquipItem(Item, MainHandTag, /*bRemoveFromInventory*/ true);
Зняття:
Equipment->TryUnequipSlot(MainHandTag, /*bReturnToInventory*/ true);
Equipment->TryUnequipAll(true);
Заміна зброї — один виклик¶
Якщо слот зайнятий, попередній предмет знімається автоматично й повертається в рюкзак. Окремо знімати не потрібно.
Повний рюкзак не знищує предмет¶
Якщо в інвентарі немає місця, зняття не відбувається: предмет лишається вдягненим,
а виклик повертає false. Нічого не втрачається через переповнений рюкзак.
Це стосується й випадку, коли вільних слотів немає, але є місце всередині стека:
предмет туди зіллється. А якщо в останню мить відмовить гейт фрагмента — предмет
повертається на себе, і виклик чесно повертає false.
Обмін між слотами¶
Equipment->TrySwapSlots(MainHandTag, OffHandTag);
Працює, якщо обидва предмети згодні жити в чужому слоті. Згода виражається в
фрагменті Equippable: слот має бути названий або як EquipmentSlot, або в
AlternativeSlots.
DA_Sword
└── Equippable
├── EquipmentSlot : Equipment.Slot.Weapon.Main ← куди потрапляє за замовчуванням
└── AlternativeSlots: Equipment.Slot.Weapon.Offhand ← і де ще може бути
Меч, що вміє тільки головну руку, у другу не переміститься — і виклик поверне
false. Це не обмеження реалізації, а те саме правило, що не дає вдягнути шолом на
ногу; просто предметам, які справді носяться в двох місцях, треба про це сказати.
Один із слотів може бути порожнім — тоді це просто «перекласти в іншу руку».
Візуальний актор¶
Якщо фрагмент Equippable називає EquippedActorClass, актор створюється й
прикріплюється на кожній машині — і на сервері, і на клієнтах.
Він не реплікується: кожен клієнт створює свій. Тому меч у руці персонажа коштує рівно стільки ж трафіку, скільки сам запис про слот.
Куди прикріплювати, вирішує GetAttachmentComponent. Типово це перший скелетний меш
власника, а якщо його немає — корінь. Перевизначте в Blueprint, якщо ваш персонаж
тримає сокети деінде: турель на транспорті, другорядний меш.
Доводка після прикріплення — OnEquipmentSpawned (матеріал за рідкістю, масштаб,
передати актору посилання на екземпляр) або подія OnEquipmentActorSpawned.
Сумарні статистики¶
Число, яке аркуш персонажа показує як «загальна броня»:
const float TotalArmor = Equipment->GetTotalStatValue(MyTags::Stat_Armor);
Підсумовує стат по всьому вдягненому. Читає значення з екземплярів, тому покращений чи пошкоджений предмет вносить свій фактичний внесок, а не номінальний для типу.
Звідки значення беруться:
Equippable.GrantedStatsпроставляє їх новій копії при створенні;- далі ваша гра може змінювати їх на конкретній копії
(
Instance->SetStatValue(...)) — заточування, зачарування, знос.
Плагін нічого не застосовує до персонажа сам: жодні дві гри не моделюють броню однаково. Він лише дає число.
Використання вдягненого¶
Equipment->TryUseEquippedItem(MainHandTag, GetPawn());
Проганяє ті самі фрагменти, що й TryUseItem для інвентаря: зламаний інструмент
відмовиться однаково — і в руці, і в рюкзаку.
Запити для UI¶
| Метод | Що дає |
|---|---|
GetEquippedItem(Slot) |
предмет у слоті або null |
GetOccupiedSlots() |
які слоти зайняті |
GetAllEntries() |
усе вдягнене одним проходом |
HasSlot(Slot) |
чи є такий слот у персонажа взагалі |
CanEquipToSlot(Item, Slot) |
чи можна вдягнути сюди — для підсвітки цілі |
GetDesiredSlotForItem(Item) |
куди предмет проситься |
GetEquippedActor(Slot) |
візуальний актор слота |
Для панелі «паперової ляльки» обходьте AvailableSlots, а не зайняті слоти —
порожній слот теж потрібно намалювати:
for (const FGameplayTag& Slot : Equipment->AvailableSlots)
{
DrawSlot(Slot, Equipment->GetEquippedItem(Slot)); // може бути null
}
Події¶
| Подія | Коли |
|---|---|
OnItemEquipped |
слот став зайнятим — саме вдягання |
OnItemUnequipped |
слот звільнився (предмет ще читабельний) |
OnEquippedItemChanged |
предмет той самий, його дані змінилися: міцність, заряди, статистика |
OnEquipmentActorSpawned |
візуальний актор створено й прикріплено |
Перші три спрацьовують і на сервері, і на клієнтах.
Чому змінa — окрема подія. Меч, яким б'ють, втрачає одиницю міцності на кожному ударі, і кожна така втрата позначає слот до реплікації. Якби це вважалося «вдяганням», звук вдягання лунав би на кожен удар. Тому: смуга міцності на панелі персонажа —
OnEquippedItemChanged; звук, спалах і перерахунок статистик —OnItemEquipped.Це рівно та сама трійка, що й в інвентаря (
OnItemAdded/OnItemRemoved/OnItemChanged), просто слот адресується тегом, а не номером.
Куди далі¶
- Створити предмет, який можна вдягнути: 03 — Створення предметів
- Розібратися з фрагментом
Equippable: 04 — Фрагменти - Зберегти вдягнене: 10 — Збереження