sasalka/README.md
2025-06-29 15:06:54 +03:00

173 lines
10 KiB
Markdown
Raw 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.

# 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 );
```