2026-07-14 11:14:13 +03:00

159 lines
4.2 KiB
C#
Raw Permalink 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 System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
//Панель с результатами открытия витрины
public class VitrinaPanel : MonoBehaviour
{
private bool initialized = false;
//запросить коробки, проверить какие требуется, найти пересечение. Если нет, то возврат.
public event Action OnComplete;
[SerializeField] private Transform BoxesRoot;
[SerializeField] private GameObject BoxViewPrefab;
private List<VitrinaBox> generatedBoxes = new();
private int pointerIndex;
[SerializeField] private float timer = 0;
private float timeToAct = 3;
VitrinaBox CurrentBox => generatedBoxes[pointerIndex];
private void OnEnable()
{
initialized = false;
}
private void OnDisable()
{
initialized = false;
ClearBoxes();
}
public void Initialize(int[] requiredBoxed)
{
if (initialized) return;
//тут проверка что есть такие коробки
int[] readyBoxes = PrizeStandController.GetReadyBoxes();
int[] res = FindIntersection(requiredBoxed, readyBoxes);
if (res.Length == 0)
{
OnComplete?.Invoke();
VitrinaCatcher.Instance.DisplayOpenResult(false, "Нет призов");
gameObject.SetActive(false);
return;
}
pointerIndex = 0;
GenerateBoxes(res);
CurrentBox.SetEnabled(true);
initialized = true;
}
public static int[] FindIntersection(int[] array1, int[] array2)
{
if (array1 == null || array2 == null || array1.Length == 0 || array2.Length == 0)
{
return Array.Empty<int>();
}
// Используем HashSet для эффективного поиска
HashSet<int> set1 = new HashSet<int>(array1);
// Находим пересечение
return array2.Where(x => set1.Contains(x)).Distinct().ToArray();
}
private void GenerateBoxes(int[] indexes)
{
if (generatedBoxes == null)
generatedBoxes = new();
foreach (int index in indexes)
{
var go = Instantiate(BoxViewPrefab, BoxesRoot);
if (go.TryGetComponent<VitrinaBox>(out var Box))
{
generatedBoxes.Add(Box);
Box.SetNumber(index);
}
else
{
Destroy(go);
Debug.Log("Префаб не содержит компонента VitrinaBoxView", gameObject);
}
}
}
private void ClearBoxes()
{
if (generatedBoxes != null)
{
foreach (var box in generatedBoxes)
Destroy(box.gameObject);
generatedBoxes.Clear();
}
}
private void Update()
{
if (!initialized) return;
var input = CollectInputs();
if (input.direction != 0)
{
int count = generatedBoxes == null ? 0 : generatedBoxes.Count;
//отобразить изменения
CurrentBox.SetEnabled(false);
CurrentBox.shake = false;
timer = 0;
pointerIndex = (pointerIndex + input.direction + count) % count;
CurrentBox.SetEnabled(true);
}
if (input.action)
{
CurrentBox.shake = true;
timer = Mathf.Clamp(timer + Time.deltaTime, 0, timeToAct);
}
else
{
CurrentBox.shake = false;
timer = 0;
}
if (timer >= timeToAct)
{
_ = PrizeStandController.OpenBoxAsync(CurrentBox.Number);
timer = 0;
OnComplete?.Invoke();
gameObject.SetActive(false);
return;
}
}
(int direction, bool action) CollectInputs()
{
int direction = (In.GetButtonDownAnyPlayer(PlayerAction.right) ? 1 : 0) -
(In.GetButtonDownAnyPlayer(PlayerAction.left) ? 1 : 0);
bool action = In.GetButtonAnyPlayer(PlayerAction.down);
return (direction, action);
}
}