Danro/Assets/Scripts/Behaviour/LevelFinish.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

125 lines
4.7 KiB
C#
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.

using UnityEngine;
using RR.Common.Controls;
using RR.Common.Settings;
using RR.Game2D.Core.Managers;
namespace RR.Game2D.Behaviour
{
/// <summary>
/// Компонент финиша уровня с возможностью выдачи маленького приза.
/// Устанавливается на объект с триггером и тегом "Finish".
/// </summary>
[RequireComponent(typeof(Collider2D))]
public class LevelFinish : MonoBehaviour
{
[Header("Настройки приза")]
[Tooltip("Включить выдачу приза при завершении уровня")]
[SerializeField] private bool enablePrizeOnFinish = true;
[Tooltip("Ключ настройки для проверки включения выдачи призов (если пусто - не проверяется)")]
[SerializeField] private string prizeEnabledSettingKey = "prizes.giveSmallPrize";
[Tooltip("Задержка перед выдачей приза (в секундах)")]
[SerializeField] private float prizeDelay = 0.5f;
[Header("Отладка")]
[SerializeField] private bool debugMode;
private bool _prizeGiven;
private void OnTriggerEnter2D(Collider2D collision)
{
// Проверяем, что это игрок
if (!collision.CompareTag("Player")) return;
// Пытаемся выдать приз
TryGivePrize();
// Переход на следующий уровень
GameManager.Instance.NextLevel();
}
/// <summary>
/// Пытается выдать приз игроку, если выполнены все условия.
/// </summary>
private void TryGivePrize()
{
// Проверка, что приз еще не был выдан
if (_prizeGiven)
{
if (debugMode)
Debug.Log("[LevelFinish] Приз уже был выдан на этом финише.");
return;
}
// Проверка, включена ли выдача призов в этом компоненте
if (!enablePrizeOnFinish)
{
if (debugMode)
Debug.Log("[LevelFinish] Выдача призов отключена в компоненте.");
return;
}
// Проверка настроек (если указан ключ)
if (!string.IsNullOrEmpty(prizeEnabledSettingKey))
{
bool settingEnabled = SettingsManager.Instance.GetBool(prizeEnabledSettingKey);
if (!settingEnabled)
{
if (debugMode)
Debug.Log($"[LevelFinish] Выдача призов отключена в настройках ({prizeEnabledSettingKey}).");
return;
}
}
// Все проверки пройдены - выдаем приз
_prizeGiven = true;
if (prizeDelay > 0)
{
Invoke(nameof(GivePrize), prizeDelay);
}
else
{
GivePrize();
}
}
/// <summary>
/// Выдает приз через PrizeSystemManager (учитывает флаг enableHopper).
/// </summary>
private void GivePrize()
{
if (debugMode)
Debug.Log("[LevelFinish] Выдаю приз игроку!");
if (RR.Common.Managers.PrizeSystemManager.Instance != null)
RR.Common.Managers.PrizeSystemManager.Instance.GivePrize();
else
PrizeSystem.GivePrize(); // fallback
}
/// <summary>
/// Сбрасывает состояние выдачи приза (для повторного использования).
/// </summary>
public void ResetPrize()
{
_prizeGiven = false;
}
#if UNITY_EDITOR
private void OnDrawGizmos()
{
// Визуализация зоны финиша в редакторе
Collider2D col = GetComponent<Collider2D>();
if (col != null)
{
Gizmos.color = enablePrizeOnFinish ? Color.green : Color.yellow;
Gizmos.DrawWireCube(col.bounds.center, col.bounds.size);
}
}
#endif
}
}