Danro/Assets/Scripts/Entities/Levitator.cs
Danil Iarosh 6da2812c8e
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
feat: add hopper prize system, prize error display, levitator component
Система выдачи призов хоппером:
- PrizeSystemManager теперь читает enableHopper из настройки prizes.giveSmallPrize
  вместо захардкоженного SerializeField (реагирует на изменения в реальном времени)
- LevelFinish: исправлен ключ настройки на prizes.giveSmallPrize
- Добавлен HopperCheckController для тестирования выдачи приза кнопкой в настройках
- Проверка датчика хоппера перенесена в ComDeviceClient (2-й бит INPUT)
- PrizeGivenBuffer заменён с PlayerPrefs на потокобезопасный Interlocked-буфер
  (исправлен краш при вызове PlayerPrefs из фонового потока платы)
- Добавлен PrizeSystem.OnPrizeResult (Action<bool>) — событие результата выдачи

Отображение ошибки выдачи приза:
- Добавлен PrizeErrorDisplay — UI-компонент, подписанный на OnPrizeResult
- Зависит от настройки prizes.showPrizeError (реагирует на изменения в реальном времени)

QR-коды:
- PrizeSystemManager подписан на изменение prizes.phoneNumber — QR-коды
  перегенерируются автоматически при смене номера
- WinBannerController показывает QR-коды только при включённой prizes.giveBigPrize

Прочее:
- Добавлен Levitator — компонент плавной левитации объекта (высота, скорость, плавность)
- Настройки: группы поддержки/тестов реорганизованы, добавлена кнопка btn.hopper_test
2026-03-06 16:47:40 +03:00

44 lines
1.7 KiB
C#

using UnityEngine;
namespace RR.Common.Behaviour
{
/// <summary>
/// Компонент левитации объекта — плавное движение вверх-вниз относительно начальной позиции.
/// </summary>
public class Levitator : MonoBehaviour
{
[Header("Параметры левитации")]
[Tooltip("Высота левитации (амплитуда отклонения от начальной позиции).")]
[SerializeField, Min(0f)] private float height = 0.1f;
[Tooltip("Скорость левитации (частота колебаний).")]
[SerializeField, Min(0f)] private float speed = 1f;
[Tooltip("Плавность движения. Чем выше значение, тем более плавные переходы на пиках.")]
[SerializeField, Range(0f, 1f)] private float smoothness = 1f;
private Vector3 _startPosition;
private float _phase;
private void Start()
{
_startPosition = transform.localPosition;
}
private void Update()
{
_phase += speed * Time.deltaTime;
// Базовое синусоидальное движение
float raw = Mathf.Sin(_phase * Mathf.PI * 2f);
// Применяем плавность: интерполяция между линейным треугольным и синусоидальным движением
float triangle = Mathf.PingPong(_phase * 2f, 2f) - 1f;
float value = Mathf.Lerp(triangle, raw, smoothness);
transform.localPosition = _startPosition + Vector3.up * (value * height);
}
}
}