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
🎯 Как использовать стакание
- В определении предмета установите
IsStackable = true - Установите
MaxCount- максимальное количество предметов в стаке - Система автоматически будет стакать предметы при добавлении в инвентарь
📈 Ожидаемые улучшения производительности
- Снижение нагрузки 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 для тестирования
В интерфейсе добавлена кнопка "📦 Выбросить все" для тестирования системы выбрасывания предметов.
Особенности реализации
- Безопасная итерация - создаются копии списков предметов для избежания ошибок при изменении коллекций
- Сетевая синхронизация - выбрасывание происходит только на владельце объекта
- Снятие экипировки - все экипированные предметы сначала снимаются, затем выбрасываются
- Случайный разброс - предметы разбрасываются случайным образом в указанном радиусе
- Специальная обработка одежды - одежда создает физические объекты с правильными метками
- Fallback система - если префаб не найден, создается простой объект с базовыми компонентами
- Логирование - все действия логируются для отладки
Использование
// Принудительно выбросить все предметы игрока
Dedugan.Local.ForceDropAllItems();
// Выбросить предметы в определенной позиции
Dedugan.Local.ForceDropAllItems( new Vector3(100, 0, 100), 30f );
// Выбросить все предметы из инвентаря напрямую
player.Inventory.DropAllItems( player.WorldPosition, 25f );
Description
Languages
C#
80.7%
HTML
8.5%
SCSS
6.3%
GLSL
4.5%