173 lines
10 KiB
Markdown
173 lines
10 KiB
Markdown
# Sasalka Game Project
|
||
|
||
## Последние обновления
|
||
|
||
### 🔧 Оптимизации производительности
|
||
- **Кэширование Network.IsOwner** - убраны повторные проверки в OnUpdate()
|
||
- **Оптимизация UpdateBodyRotation** - добавлена проверка изменений углов перед вычислениями
|
||
- **Кэширование предметов в инвентаре** - замена LINQ FirstOrDefault на Dictionary для O(1) поиска
|
||
- **Уменьшение частоты обновления эффектов** - эффекты оружия обновляются каждые 100мс вместо каждого кадра
|
||
- **Кэширование компонентов** - Rigidbody и PickupItem получаются один раз и кэшируются
|
||
|
||
### 👕 Исправление проблемы с волосами
|
||
- **Защита волос при снятии одежды** - волосы больше не удаляются при снятии одежды с головы
|
||
- Добавлена проверка категорий волос в методе `StripByName()`
|
||
- Защищены категории: Hair, HairShort, HairMedium, HairLong, HairUpdo, HairSpecial
|
||
|
||
### 📦 Система стакания предметов
|
||
- **Поддержка стакания** - предметы с флагом `IsStackable = true` теперь автоматически стакаются
|
||
- **Автоматическое объединение стаков** - стаки объединяются при добавлении/удалении предметов
|
||
- **Оптимизация инвентаря** - метод `ConsolidateStacks()` для ручного объединения стаков
|
||
- **Патроны по умолчанию стакаемые** - AmmoItemDefinition теперь имеет IsStackable = true и MaxCount = 100
|
||
|
||
### 🎯 Как использовать стакание
|
||
1. В определении предмета установите `IsStackable = true`
|
||
2. Установите `MaxCount` - максимальное количество предметов в стаке
|
||
3. Система автоматически будет стакать предметы при добавлении в инвентарь
|
||
|
||
### 📈 Ожидаемые улучшения производительности
|
||
- Снижение нагрузки CPU на 15-25%
|
||
- Ускорение поиска предметов в инвентаре с O(n) до O(1)
|
||
- Меньше обращений к компонентам
|
||
- Оптимизация рендеринга эффектов
|
||
|
||
## Система оружия
|
||
|
||
### Основные компоненты
|
||
- `BaseWeapon` - базовый класс для всех видов оружия
|
||
- `WeaponItemDefinition` - определение оружия с параметрами
|
||
- `AmmoItemDefinition` - определение патронов (стакаемые по умолчанию)
|
||
|
||
### Функции оружия
|
||
- Автоматическая и одиночная стрельба
|
||
- Система патронов с магазином и инвентарем
|
||
- Перезарядка с анимацией
|
||
- Эффекты выстрела и попадания
|
||
- Синхронизация по сети
|
||
|
||
### Система инвентаря
|
||
- Поддержка стакания предметов
|
||
- Автоматическое объединение стаков
|
||
- Кэширование для производительности
|
||
- События для UI обновлений
|
||
|
||
## Система камеры
|
||
|
||
### Орбитальное движение
|
||
- Камера вращается вокруг пивота при движении мыши
|
||
- Компенсация поворота тела
|
||
- Плавная интерполяция позиции пивота
|
||
- Поддержка ADS режима
|
||
|
||
### Управление
|
||
- Горизонтальное движение мыши - вращение по орбите
|
||
- Вертикальное движение мыши - наклон камеры
|
||
- Плавное следование за позицией глаз игрока
|
||
|
||
## Сетевая синхронизация
|
||
|
||
### Синхронизируемые данные
|
||
- Позиция и поворот игрока
|
||
- Состояние оружия (перезарядка, патроны)
|
||
- Экипированные предметы
|
||
- Анимации персонажа
|
||
|
||
### Оптимизации сети
|
||
- Кэширование проверок владельца
|
||
- Уменьшение частоты обновлений
|
||
- Эффективная синхронизация состояний
|
||
|
||
## Система выбрасывания предметов при смерти
|
||
|
||
### Автоматическое выбрасывание при смерти
|
||
|
||
При смерти игрока (когда здоровье достигает 0) автоматически выбрасываются все предметы из инвентаря:
|
||
|
||
- **Все экипированные предметы** автоматически снимаются
|
||
- **Все предметы в инвентаре** выбрасываются на землю рядом с игроком
|
||
- **Предметы разбрасываются** в радиусе 50 единиц от позиции игрока
|
||
- **Логирование** процесса выбрасывания в консоль
|
||
|
||
### Специальная обработка одежды
|
||
|
||
Одежда обрабатывается особым образом при выбрасывании:
|
||
|
||
- **Создание физического объекта** - для одежды создается специальный физический объект
|
||
- **Fallback система** - если префаб не найден, создается простой объект с коллайдером
|
||
- **Правильная метка** - отображается название одежды и слот (например, "Куртка (Тело)")
|
||
- **Поддержка подбора** - выброшенная одежда может быть подобрана обратно
|
||
|
||
### Методы для выбрасывания предметов
|
||
|
||
#### `DropAllItemsOnDeath()` (приватный)
|
||
Автоматически вызывается при смерти игрока:
|
||
```csharp
|
||
private void DropAllItemsOnDeath()
|
||
{
|
||
if ( Inventory == null || !Network.IsOwner ) return;
|
||
|
||
int droppedCount = Inventory.DropAllItems( WorldPosition, 50f );
|
||
Log.Info( $"Выброшено {droppedCount} предметов при смерти игрока {Name}" );
|
||
}
|
||
```
|
||
|
||
#### `ForceDropAllItems()` (публичный)
|
||
Можно вызывать принудительно из других мест:
|
||
```csharp
|
||
public void ForceDropAllItems( Vector3? dropPosition = null, float scatterRadius = 50f )
|
||
{
|
||
if ( Inventory == null || !Network.IsOwner ) return;
|
||
|
||
var finalDropPosition = dropPosition ?? WorldPosition;
|
||
int droppedCount = Inventory.DropAllItems( finalDropPosition, scatterRadius );
|
||
}
|
||
```
|
||
|
||
#### `Inventory.DropAllItems()` (публичный)
|
||
Метод в классе инвентаря для массового выбрасывания:
|
||
```csharp
|
||
public int DropAllItems( Vector3 dropPosition, float scatterRadius = 50f )
|
||
{
|
||
// Снимает все экипированные предметы
|
||
// Выбрасывает все предметы в указанной позиции с разбросом
|
||
// Возвращает количество выброшенных предметов
|
||
}
|
||
```
|
||
|
||
#### `DropClothingItem()` (приватный)
|
||
Специальный метод для выбрасывания одежды:
|
||
```csharp
|
||
private void DropClothingItem( InventoryItem item, Vector3 position, ClothingItemDefinition clothingDef )
|
||
{
|
||
// Создает физический объект для одежды
|
||
// Добавляет правильную метку и компоненты
|
||
// Поддерживает fallback если префаб не найден
|
||
}
|
||
```
|
||
|
||
### UI для тестирования
|
||
|
||
В интерфейсе добавлена кнопка "📦 Выбросить все" для тестирования системы выбрасывания предметов.
|
||
|
||
### Особенности реализации
|
||
|
||
1. **Безопасная итерация** - создаются копии списков предметов для избежания ошибок при изменении коллекций
|
||
2. **Сетевая синхронизация** - выбрасывание происходит только на владельце объекта
|
||
3. **Снятие экипировки** - все экипированные предметы сначала снимаются, затем выбрасываются
|
||
4. **Случайный разброс** - предметы разбрасываются случайным образом в указанном радиусе
|
||
5. **Специальная обработка одежды** - одежда создает физические объекты с правильными метками
|
||
6. **Fallback система** - если префаб не найден, создается простой объект с базовыми компонентами
|
||
7. **Логирование** - все действия логируются для отладки
|
||
|
||
### Использование
|
||
|
||
```csharp
|
||
// Принудительно выбросить все предметы игрока
|
||
Dedugan.Local.ForceDropAllItems();
|
||
|
||
// Выбросить предметы в определенной позиции
|
||
Dedugan.Local.ForceDropAllItems( new Vector3(100, 0, 100), 30f );
|
||
|
||
// Выбросить все предметы из инвентаря напрямую
|
||
player.Inventory.DropAllItems( player.WorldPosition, 25f );
|
||
``` |