Danro/Assets/Scripts/Entities/Props/BatCollectible.cs
Danil Iarosh cb2e83a596
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
feat(ui, prizes, spawners, editor): expand prize flow and add spawning/editor tooling
- доработан flow призовой витрины и связанного UI:
  добавлены `PrizeStandButtonView` и `RulesPrizeListPage`, обновлены
  `PrizeStandController`, `PrizeStandPrize`, `PrizeStandModal`,
  `PrizeStandSettingsModal`, `LevelPrizeSettingsModal`, `QRCodeSettingsModal`,
  `BalanceDisplay`, `ButtonTextFocusColor` и связанные prefab'ы,
  чтобы улучшить настройку, навигацию, отображение кнопок и prize flow
- расширена система настроек и сохранения значений:
  `OptionPicker` получил отдельный формат `ValueSelector`,
  обновлены `SettingsDatabase`, `SettingEntryDrawer`, `SettingUIItem`,
  `SettingsUIGenerator`, `ValueSelectorRow` и `MainSettingsDatabase.asset`,
  а сохранение option picker-значений, включая `gameplay.gameDifficulty`,
  исправлено и синхронизировано с остальными настройками
- добавлены универсальные спавнеры сущностей:
  реализованы `EntitySpawner` и `EntitySpawnerManager` с поддержкой
  весов префабов, точек спавна, заполнения по проценту, ограничений
  на количество и автоспавна при инициализации
- доработана логика игрового спавна и сложности:
  процент инициализационного спавна может зависеть от настройки
  `gameplay.gameDifficulty` с градациями 25/50/75/100,
  в одном цикле массового спавна повторно не используется та же точка,
  а gizmo спавнера теперь показывает только сами точки без линий
- упрощена работа в редакторе Unity и добавлены editor-инструменты:
  в `GameManager` лицензия пропускается при запуске в `UNITY_EDITOR`,
  а `HierarchySelectionCounter`, `HierarchySelectionCountOverlay`
  и `HierarchyBulkRenamerWindow` добавляют подсчет выделения,
  realtime overlay в `SceneView` и массовое переименование объектов
  по правилам нумерации из Unity Project Settings
- синхронизированы сцены, ресурсы и UI-ассеты под новый flow:
  обновлены `MainMenu`, `Level UI`, уровни `1-1` и `1-2`,
  строки настроек, кнопки, TMP/font assets, изображения UI,
  `prizes.json` и recovery-данные после правок интерфейса и логики
- очищены и переразложены часть внешних и служебных ресурсов:
  удалён пакет `Lava_Flowing_Shader`, переименованы/заменены
  отдельные UI-prefab'ы и добавлены сопутствующие проектные артефакты,
  которые сейчас используются обновлённой конфигурацией проекта
2026-04-28 14:05:05 +03:00

80 lines
2.9 KiB
C#

using UnityEngine;
namespace RR.Common.Entities.Props
{
public sealed class BatCollectible : EnvironmentalCollectibleBase
{
public override bool CountsTowardsSharedCollectionLimit => true;
[SerializeField] private float moveSpeed = 1.75f;
[SerializeField] private float verticalAmplitude = 0.35f;
[SerializeField] private float verticalFrequency = 2.4f;
[SerializeField] private float horizontalWaveAmplitude = 0.2f;
[SerializeField] private float horizontalWaveFrequency = 1.35f;
[SerializeField] private float maxRange = 3.5f;
[SerializeField] private float directionChangeIntervalMin = 1.5f;
[SerializeField] private float directionChangeIntervalMax = 3.5f;
private Vector3 _anchorPosition;
private Vector3 _currentPosition;
private float _time;
private float _directionTimer;
private float _nextDirectionChangeTime;
private int _moveDirection;
protected override void OnSpawned()
{
_anchorPosition = SpawnPosition;
_currentPosition = transform.position;
_time = 0f;
_directionTimer = 0f;
_moveDirection = 1;
_nextDirectionChangeTime = Random.Range(directionChangeIntervalMin, directionChangeIntervalMax);
}
protected override void TickBehaviour(float dt)
{
_time += dt;
_directionTimer += dt;
if (_directionTimer >= _nextDirectionChangeTime)
{
FlipDirection();
_directionTimer = 0f;
_nextDirectionChangeTime = Random.Range(directionChangeIntervalMin, directionChangeIntervalMax);
}
Vector3 position = _currentPosition;
position.x += _moveDirection * moveSpeed * dt;
float xOffsetFromAnchor = position.x - _anchorPosition.x;
if (Mathf.Abs(xOffsetFromAnchor) > maxRange)
{
position.x = _anchorPosition.x + Mathf.Sign(xOffsetFromAnchor) * maxRange;
FlipDirection();
_directionTimer = 0f;
_nextDirectionChangeTime = Random.Range(directionChangeIntervalMin, directionChangeIntervalMax);
}
float verticalOffset = Mathf.Sin(_time * verticalFrequency) * verticalAmplitude;
float horizontalOffset = Mathf.Sin(_time * horizontalWaveFrequency) * horizontalWaveAmplitude;
position.y = _anchorPosition.y + verticalOffset;
position.x += horizontalOffset * dt;
_currentPosition = position;
transform.position = position;
}
private void FlipDirection()
{
_moveDirection = -_moveDirection;
Vector3 scale = transform.localScale;
float xScale = Mathf.Abs(scale.x);
scale.x = _moveDirection > 0 ? xScale : -xScale;
transform.localScale = scale;
}
}
}