sasalka/Code/Weapons/README.md
2025-06-28 21:46:34 +03:00

153 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Универсальная система используемых предметов
## Обзор
Система построена на принципах наследования и интерфейсов. Любой предмет в руках может реализовывать интерфейс `IUseable` и иметь свою уникальную логику использования.
## Архитектура
### IUseable
Интерфейс для всех используемых предметов:
- `CanUse()` - проверка возможности использования
- `Use()` - выполнение действия
- `Cooldown` - время перезарядки между использованиями
### BaseWeapon
Базовый класс для оружия, **наследуется от InventoryItem** и реализует `IUseable`. Содержит:
- Логику стрельбы и трассировки пуль
- Управление патронами (магазин + инвентарь)
- Систему перезарядки
- Эффекты выстрела и попадания
- Автоматическую стрельбу
- **Физику** - автоматическое отключение RigidBody при экипировке
### Flashlight
Пример другого используемого предмета - фонарика. Показывает:
- Как создавать предметы с собственной логикой
- Переключение состояний (вкл/выкл)
- Звуковые эффекты
### WeaponFactory
Универсальная фабрика для создания любых используемых предметов.
## Ключевые особенности
### 1. Наследование от InventoryItem
- **BaseWeapon наследуется от InventoryItem** - не нужно вешать 2 компонента на префаб
- Один компонент = один предмет в инвентаре
- Автоматическое управление состоянием экипировки
### 2. Автоматическая стрельба
- Оружие стреляет автоматически при удержании кнопки мыши **только если IsAutomatic = true**
- Для полуавтоматического оружия (IsAutomatic = false) - только одиночные выстрелы
- **Частота стрельбы берется из WeaponItemDefinition.FireRate**
### 3. Система патронов
- **Оружие начинается с пустым магазином** - патроны нужно зарядить
- **Сохранение патронов в магазине** - при выбрасывании оружия патроны остаются
- **Патроны сохраняются при снятии/экипировке** - патроны в магазине не теряются при переключении оружия
- Патроны хранятся в инвентаре как отдельные предметы
- **Стрельба зависит ТОЛЬКО от патронов в магазине** - CurrentAmmo
- **HUD показывает патроны в магазине** - не зависит от инвентаря
- **Патроны тратятся только из магазина при выстреле** - CurrentAmmo уменьшается
- **Патроны тратятся из инвентаря только при перезарядке** - загружаются в магазин
- **Перезарядка только вручную** - кнопка R или автоматически при пустом магазине
- **Анимация перезарядки оружия** - `b_reload` параметр анимации оружия
- **Анимация перезарядки персонажа** - `b_reload` параметр анимации персонажа
- **Скорость анимации перезарядки** - `speed_reload` параметр для контроля скорости анимации (рассчитывается как 1/ReloadTime)
- **Безопасная обработка неполных магазинов** - загружается столько патронов, сколько есть в инвентаре
### 4. HUD и UI
- **Отображение патронов в магазине** (текущие/максимум)
- **Отображение патронов в инвентаре** (общее количество)
- **Прогресс перезарядки** в реальном времени
- Формат: `15/30 (45)` - где 15 в магазине, 30 максимум, 45 всего в инвентаре
### 5. Физика
- **Автоматическое отключение RigidBody при экипировке**
- **Включение физики при снятии оружия**
- Предметы не падают когда в руках
### 6. Настройка в префабах
- Не нужно создавать отдельные файлы для каждого оружия
- Настройка происходит прямо в инстансе префаба
- Компоненты добавляются автоматически
### 7. Логика вращения в ADS режиме
- **При беге (velocity > 10)**: Тело центрируется при угле > 15° (как в обычном режиме)
- **При стоянии на месте**: Мертвая зона 85° - тело поворачивается только при угле > 85°
- **Синхронизация**: Логика работает одинаково для всех игроков
### 8. Синхронизация анимаций
- **Перезарядка**: Анимации перезарядки синхронизированы по сети
- **RPC вызовы**: StartReload и FinishReload используют [Rpc.Broadcast]
- **Скорость анимации**: speed_reload параметр синхронизирован для всех игроков
## Практическое использование
### 1. Создание оружия в редакторе
#### Шаг 1: Создание префаба
1. Создайте новый GameObject в сцене
2. Добавьте модель оружия (SkinnedModelRenderer)
3. Добавьте компонент `BaseWeapon`
4. Настройте параметры в инспекторе:
- `GunRenderer` - ссылка на рендерер оружия
- `MuzzleLight` - свет вспышки
- `ParticlePrefab` - эффекты попадания
- `BloodParticle` - эффекты крови
- `Cooldown` - время между выстрелами
#### Шаг 2: Создание WeaponItemDefinition
1. В Project Settings создайте новый ресурс типа "Weapon Item Definition"
2. Настройте параметры:
```
Name: "Pistol"
Slot: RightHand
HoldType: Pistol
Damage: 25
FireRate: 8
Range: 1000
MagazineSize: 15
AmmoType: "Pistol"
ReloadTime: 2.0
Spread: 0.02
```
3. Укажите префаб в поле `Prefab`
#### Шаг 3: Добавление в игру
```csharp
// В коде игрока или менеджера
var weaponDef = ResourceLibrary.Get<WeaponItemDefinition>("Items/pistol.weapon");
var weaponItem = WeaponFactory.CreateWeaponItem(weaponDef);
player.Inventory.AddItem(weaponItem);
```
### 2. Создание фонарика
#### Шаг 1: Создание префаба фонарика
1. Создайте GameObject с моделью фонарика
2. Добавьте компонент `Flashlight`
3. Настройте параметры:
- `LightSource` - GameObject с источником света
- `ToggleSound` - звук включения/выключения
- `Cooldown` - время между переключениями
#### Шаг 2: Создание ItemDefinition
```csharp
// Создайте BaseItemDefinition или WeaponItemDefinition
// Name: "Flashlight"
// Slot: LeftHand
// Prefab: ссылка на префаб фонарика
```
#### Шаг 3: Использование
```csharp
var flashlightDef = ResourceLibrary.Get<BaseItemDefinition>("Items/flashlight.item");
var flashlightItem = WeaponFactory.CreateItem(flashlightDef);
player.Inventory.AddItem(flashlightItem);
```
### 3. Создание собственного предмета
```