Спроектируйте систему оружия для соревновательного мультиплеерного шутера в Unreal Engine. В игре десятки стволов — hitscan-винтовки, projectile-гранатомёты, разные скорострельность, урон, разброс и размеры магазина, — и дизайнеры должны добавлять и балансировать новое оружие без программиста и пересборки. Два игрока с одним и тем же стволом должны вести независимое число патронов и состояние перезарядки. Стрельба должна ощущаться мгновенно отзывчивой на стреляющем клиенте, но попадания и убийства должны быть авторитетными и недоверяемыми клиенту (читеры не должны подделывать урон). Опишите, как вы структурируете логику оружия, где живут описания оружия, кто владеет состоянием стрельбы и как выстрелы, попадания и косметика разделены между клиентом и сервером. Назовите компромиссы вашей структуры.
Сделайте оружие через UWeaponComponent (или прикреплённый Actor), управляемый UWeaponDataAsset для скорострельности, урона и патронов. Компонент владеет состоянием стрельбы; сервер валидирует выстрелы и применяет попадания, а клиент предсказывает VFX дула и отдачу.
- ✗Жёстко зашивать характеристики оружия в C++
производные классывместо общего описания на данных - ✗Доверять попаданиям от клиента, позволяя игрокам подделывать убийства
- ✗Использовать заспавненный снаряд-Actor для hitscan-оружия, где достаточно линейного трейса
- →Как бы вы реализовали смену оружия и сохранение состояния патронов на каждое оружие?
- →Чем hitscan- и projectile-оружие отличаются по требованиям к репликации?
Ключевые классы
UWeaponDataAsset— описание: скорострельность, урон, разброс, размер магазина, тип (hitscan/projectile), ассеты VFX и звука.UWeaponComponent—UActorComponentна персонаже: владеет текущим патроном, кулдауном выстрела, состоянием перезарядки.AProjectile— отдельныйActorтолько для оружия типа projectile (гранатомёты, луки).UWeaponInstance—USTRUCTили объект с состоянием экземпляра: патроны в магазине, прочность.
Модель данных
Поведение оружия — это данные: UWeaponComponent исполняет один общий алгоритм, читая UWeaponDataAsset. Состояние (патроны, кулдаун) отделено от описания, поэтому два игрока с одинаковым стволом имеют разное число патронов.
Поток данных
- Клиент жмёт огонь → локально предсказывает VFX дула, отдачу, звук.
- Server RPC
Fire(AimDir); сервер проверяет кулдаун и патроны. - Hitscan → линейный трейс на сервере; projectile → спавн
AProjectile. - Сервер применяет урон, реплицирует патроны, multicast'ом рассылает попадание для удалённых клиентов.
Репликация
Патроны и состояние перезарядки реплицируются сервером. Hitscan-выстрел подтверждается Multicast RPC (трассеры, decal). Projectile-актор реплицируется как обычный Actor. Косметика дула предсказывается локально и не ждёт сервера.
Настройка дизайнером
Каждый ствол — ассет UWeaponDataAsset. Создание нового оружия = новый ассет, без кода. Кривые отдачи — UCurveFloat. Лут-таблицы оружия — DataTable.
Компромиссы
- Компонент vs. отдельный Actor оружия: Actor удобен для видимой модели и физики на земле; компонент проще для логики. Часто комбинируют: Actor для меша + компонент для логики.
- Hitscan vs. projectile: hitscan дёшев и мгновенен, но не даёт баллистики; projectile реалистичнее, но дороже по сети.