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

10 KiB
Raw Blame History

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() (приватный)

Автоматически вызывается при смерти игрока:

private void DropAllItemsOnDeath()
{
    if ( Inventory == null || !Network.IsOwner ) return;
    
    int droppedCount = Inventory.DropAllItems( WorldPosition, 50f );
    Log.Info( $"Выброшено {droppedCount} предметов при смерти игрока {Name}" );
}

ForceDropAllItems() (публичный)

Можно вызывать принудительно из других мест:

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() (публичный)

Метод в классе инвентаря для массового выбрасывания:

public int DropAllItems( Vector3 dropPosition, float scatterRadius = 50f )
{
    // Снимает все экипированные предметы
    // Выбрасывает все предметы в указанной позиции с разбросом
    // Возвращает количество выброшенных предметов
}

DropClothingItem() (приватный)

Специальный метод для выбрасывания одежды:

private void DropClothingItem( InventoryItem item, Vector3 position, ClothingItemDefinition clothingDef )
{
    // Создает физический объект для одежды
    // Добавляет правильную метку и компоненты
    // Поддерживает fallback если префаб не найден
}

UI для тестирования

В интерфейсе добавлена кнопка "📦 Выбросить все" для тестирования системы выбрасывания предметов.

Особенности реализации

  1. Безопасная итерация - создаются копии списков предметов для избежания ошибок при изменении коллекций
  2. Сетевая синхронизация - выбрасывание происходит только на владельце объекта
  3. Снятие экипировки - все экипированные предметы сначала снимаются, затем выбрасываются
  4. Случайный разброс - предметы разбрасываются случайным образом в указанном радиусе
  5. Специальная обработка одежды - одежда создает физические объекты с правильными метками
  6. Fallback система - если префаб не найден, создается простой объект с базовыми компонентами
  7. Логирование - все действия логируются для отладки

Использование

// Принудительно выбросить все предметы игрока
Dedugan.Local.ForceDropAllItems();

// Выбросить предметы в определенной позиции
Dedugan.Local.ForceDropAllItems( new Vector3(100, 0, 100), 30f );

// Выбросить все предметы из инвентаря напрямую
player.Inventory.DropAllItems( player.WorldPosition, 25f );