upd
This commit is contained in:
@@ -22,7 +22,6 @@ public class BaseWeapon : InventoryItem, IUseable
|
||||
[Property] public GameObject EjectTransform { get; set; }
|
||||
|
||||
// Состояние оружия
|
||||
[Sync] public int CurrentAmmo { get; set; }
|
||||
[Sync] public bool IsReloading { get; set; }
|
||||
[Sync] public TimeSince TimeSinceLastShot { get; set; }
|
||||
[Sync] public TimeSince TimeSinceReloadStart { get; set; }
|
||||
@@ -35,6 +34,7 @@ public class BaseWeapon : InventoryItem, IUseable
|
||||
// Кэш для производительности
|
||||
private WeaponItemDefinition _weaponDefinition;
|
||||
private bool _isInitialized;
|
||||
private InventoryItem _inventoryItem;
|
||||
|
||||
// IUseable реализация - Cooldown вычисляется на основе FireRate
|
||||
public float Cooldown
|
||||
@@ -46,6 +46,32 @@ public class BaseWeapon : InventoryItem, IUseable
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Установить ссылку на InventoryItem
|
||||
/// </summary>
|
||||
public void SetInventoryItem( InventoryItem item )
|
||||
{
|
||||
_inventoryItem = item;
|
||||
|
||||
// Инициализируем оружие после установки InventoryItem
|
||||
InitializeWeapon();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить количество патронов в магазине из InventoryItem
|
||||
/// </summary>
|
||||
public int CurrentAmmo
|
||||
{
|
||||
get => _inventoryItem?.MagazineAmmo ?? 0;
|
||||
set
|
||||
{
|
||||
if ( _inventoryItem != null )
|
||||
{
|
||||
_inventoryItem.MagazineAmmo = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
base.OnStart();
|
||||
@@ -54,8 +80,7 @@ public class BaseWeapon : InventoryItem, IUseable
|
||||
_sound = GameObject.GetComponent<SoundPointComponent>( true );
|
||||
_pickupItem = GameObject.Components.Get<PickupItem>();
|
||||
|
||||
// Инициализируем оружие
|
||||
InitializeWeapon();
|
||||
// Инициализация оружия будет вызвана после установки InventoryItem
|
||||
}
|
||||
|
||||
protected override void OnUpdate()
|
||||
@@ -88,8 +113,7 @@ public class BaseWeapon : InventoryItem, IUseable
|
||||
return;
|
||||
}
|
||||
|
||||
// Оружие начинается с пустым магазином - патроны нужно зарядить
|
||||
CurrentAmmo = 0;
|
||||
// Инициализация завершена
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
@@ -308,6 +332,24 @@ public class BaseWeapon : InventoryItem, IUseable
|
||||
IsReloading = true;
|
||||
TimeSinceReloadStart = 0;
|
||||
|
||||
var weaponDef = GetWeaponDefinition();
|
||||
float reloadSpeed = weaponDef?.ReloadTime > 0 ? 1f / weaponDef.ReloadTime : 1f;
|
||||
|
||||
// Анимация перезарядки оружия
|
||||
if ( GunRenderer != null )
|
||||
{
|
||||
GunRenderer.Set( "b_reload", true );
|
||||
GunRenderer.Set( "speed_reload", reloadSpeed );
|
||||
}
|
||||
|
||||
// Анимация перезарядки персонажа
|
||||
var player = Dedugan.Local;
|
||||
if ( player?.Renderer != null )
|
||||
{
|
||||
player.Renderer.Set( "b_reload", true );
|
||||
player.Renderer.Set( "speed_reload", reloadSpeed );
|
||||
}
|
||||
|
||||
// Эффекты перезарядки
|
||||
PlayReloadEffects();
|
||||
}
|
||||
@@ -319,6 +361,21 @@ public class BaseWeapon : InventoryItem, IUseable
|
||||
{
|
||||
IsReloading = false;
|
||||
|
||||
// Сбрасываем анимацию перезарядки оружия
|
||||
if ( GunRenderer != null )
|
||||
{
|
||||
GunRenderer.Set( "b_reload", false );
|
||||
GunRenderer.Set( "speed_reload", 1f );
|
||||
}
|
||||
|
||||
// Сбрасываем анимацию перезарядки персонажа
|
||||
var player = Dedugan.Local;
|
||||
if ( player?.Renderer != null )
|
||||
{
|
||||
player.Renderer.Set( "b_reload", false );
|
||||
player.Renderer.Set( "speed_reload", 1f );
|
||||
}
|
||||
|
||||
var weaponDef = GetWeaponDefinition();
|
||||
if ( weaponDef == null ) return;
|
||||
|
||||
|
||||
@@ -45,12 +45,16 @@
|
||||
### 3. Система патронов
|
||||
- **Оружие начинается с пустым магазином** - патроны нужно зарядить
|
||||
- **Сохранение патронов в магазине** - при выбрасывании оружия патроны остаются
|
||||
- **Патроны сохраняются при снятии/экипировке** - патроны в магазине не теряются при переключении оружия
|
||||
- Патроны хранятся в инвентаре как отдельные предметы
|
||||
- **Стрельба зависит ТОЛЬКО от патронов в магазине** - CurrentAmmo
|
||||
- **HUD показывает патроны в магазине** - не зависит от инвентаря
|
||||
- **Патроны тратятся только из магазина при выстреле** - CurrentAmmo уменьшается
|
||||
- **Патроны тратятся из инвентаря только при перезарядке** - загружаются в магазин
|
||||
- **Перезарядка только вручную** - кнопка R или автоматически при пустом магазине
|
||||
- **Анимация перезарядки оружия** - `b_reload` параметр анимации оружия
|
||||
- **Анимация перезарядки персонажа** - `b_reload` параметр анимации персонажа
|
||||
- **Скорость анимации перезарядки** - `speed_reload` параметр для контроля скорости анимации (рассчитывается как 1/ReloadTime)
|
||||
- **Безопасная обработка неполных магазинов** - загружается столько патронов, сколько есть в инвентаре
|
||||
|
||||
### 4. HUD и UI
|
||||
@@ -136,130 +140,4 @@ player.Inventory.AddItem(flashlightItem);
|
||||
|
||||
### 3. Создание собственного предмета
|
||||
|
||||
```csharp
|
||||
// Создайте новый класс
|
||||
public sealed class Medkit : Component, IUseable
|
||||
{
|
||||
[Property] public float Cooldown { get; set; } = 5f;
|
||||
[Property] public int HealAmount { get; set; } = 50;
|
||||
|
||||
private TimeSince _lastUseTime;
|
||||
|
||||
public bool CanUse()
|
||||
{
|
||||
return IsValid && _lastUseTime >= Cooldown;
|
||||
}
|
||||
|
||||
public void Use()
|
||||
{
|
||||
if (!CanUse()) return;
|
||||
|
||||
_lastUseTime = 0;
|
||||
|
||||
// Логика лечения
|
||||
var player = Dedugan.Local;
|
||||
if (player != null)
|
||||
{
|
||||
player.Health = Math.Min(player.Health + HealAmount, 100);
|
||||
Log.Info($"Игрок вылечен на {HealAmount} HP");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## WeaponFactory - подробное руководство
|
||||
|
||||
### Основные методы:
|
||||
|
||||
#### 1. `CreateUseableItem(BaseItemDefinition, InventoryItem)`
|
||||
Создает любой используемый предмет:
|
||||
```csharp
|
||||
var itemDef = ResourceLibrary.Get<BaseItemDefinition>("path/to/item");
|
||||
var item = WeaponFactory.CreateUseableItem(itemDef, inventoryItem);
|
||||
```
|
||||
|
||||
#### 2. `CreateWeapon(WeaponItemDefinition, InventoryItem)`
|
||||
Создает оружие (для обратной совместимости):
|
||||
```csharp
|
||||
var weaponDef = ResourceLibrary.Get<WeaponItemDefinition>("path/to/weapon");
|
||||
var weapon = WeaponFactory.CreateWeapon(weaponDef, inventoryItem);
|
||||
```
|
||||
|
||||
#### 3. `CreateItem(BaseItemDefinition)`
|
||||
Создает предмет для инвентаря:
|
||||
```csharp
|
||||
var itemDef = ResourceLibrary.Get<BaseItemDefinition>("path/to/item");
|
||||
var inventoryItem = WeaponFactory.CreateItem(itemDef);
|
||||
```
|
||||
|
||||
### Автоматическое определение типа
|
||||
|
||||
WeaponFactory автоматически определяет тип предмета по имени:
|
||||
|
||||
- **Оружие**: содержит "pistol", "rifle", "gun" → создается `BaseWeapon`
|
||||
- **Фонарик**: содержит "flashlight", "light" → создается `Flashlight`
|
||||
- **По умолчанию**: создается `BaseWeapon`
|
||||
|
||||
### Примеры использования
|
||||
|
||||
#### Создание пистолета:
|
||||
```csharp
|
||||
// 1. Создаем предмет для инвентаря
|
||||
var pistolDef = ResourceLibrary.Get<WeaponItemDefinition>("Items/pistol.weapon");
|
||||
var pistolItem = WeaponFactory.CreateWeaponItem(pistolDef);
|
||||
|
||||
// 2. Добавляем в инвентарь
|
||||
player.Inventory.AddItem(pistolItem);
|
||||
|
||||
// 3. Экипируем
|
||||
player.Inventory.EquipItem(pistolItem);
|
||||
```
|
||||
|
||||
#### Создание фонарика:
|
||||
```csharp
|
||||
// 1. Создаем предмет
|
||||
var flashlightDef = ResourceLibrary.Get<BaseItemDefinition>("Items/flashlight.item");
|
||||
var flashlightItem = WeaponFactory.CreateItem(flashlightDef);
|
||||
|
||||
// 2. Добавляем в инвентарь
|
||||
player.Inventory.AddItem(flashlightItem);
|
||||
```
|
||||
|
||||
#### Создание аптечки:
|
||||
```csharp
|
||||
// 1. Создаем предмет
|
||||
var medkitDef = ResourceLibrary.Get<BaseItemDefinition>("Items/medkit.item");
|
||||
var medkitItem = WeaponFactory.CreateItem(medkitDef);
|
||||
|
||||
// 2. Добавляем в инвентарь
|
||||
player.Inventory.AddItem(medkitItem);
|
||||
```
|
||||
|
||||
## Настройка в префабах
|
||||
|
||||
### Для оружия:
|
||||
1. Добавьте компонент `BaseWeapon`
|
||||
2. Настройте все необходимые ссылки (рендерер, звуки, эффекты)
|
||||
3. Установите параметры стрельбы (Cooldown, FireRate и т.д.)
|
||||
|
||||
### Для других предметов:
|
||||
1. Добавьте компонент, реализующий `IUseable`
|
||||
2. Настройте специфичные параметры
|
||||
3. Реализуйте логику в методах `CanUse()` и `Use()`
|
||||
|
||||
## Преимущества системы
|
||||
|
||||
1. **Универсальность** - один интерфейс для всех предметов
|
||||
2. **Гибкость** - каждый предмет может иметь свою логику
|
||||
3. **Простота** - настройка в префабах, без создания отдельных файлов
|
||||
4. **Расширяемость** - легко добавлять новые типы предметов
|
||||
5. **Производительность** - кэширование и оптимизация
|
||||
6. **Читаемость** - понятная структура и документация
|
||||
|
||||
## Примеры предметов
|
||||
|
||||
- **Оружие** - стрельба, перезарядка, патроны
|
||||
- **Фонарик** - включение/выключение света
|
||||
- **Аптечка** - лечение игрока
|
||||
- **Инструменты** - ремонт, строительство
|
||||
- **Еда** - восстановление здоровья/голода
|
||||
```
|
||||
Reference in New Issue
Block a user