using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using TMPro; public class RulesPrizePanel : MonoBehaviour { [SerializeField] RectTransform ScaleContainer; [SerializeField] GameObject IconTemplate; [SerializeField] GameObject PointNumberTemplate; [SerializeField] float IconSize = 100; [SerializeField] float PointSize = 30; [SerializeField] float SubpointSize = 15; [SerializeField] float PointOffsetX = 100; [SerializeField] float LinkWidth = 5; [SerializeField] float StrokeWidth = 15; [SerializeField] float StrokeGap = 15; [SerializeField] float prizetextFontsize = 30; [SerializeField] float instructionFontsize = 24; [SerializeField] Sprite circle; [SerializeField] Sprite square; [SerializeField] Sprite giftSprite; [SerializeField] Color ScaleColor = Color.gray; [SerializeField] Color ScaleColorHighlighted = new Color(1, .7f, 0); private Character[] characters; private List prizes; List generatedObjects; List generatedIcons; List generatedPoints; List generatedLinks; List generatedSubpoints; [SerializeField] RectTransform InstructionContainer; private void OnEnable() => GenerateScale(); private void OnDisable() => Clear(); /* private void OnValidate() { Clear(); GenerateScale(); }*/ private void Clear() { for (int i = generatedObjects.Count - 1; i >= 0; i--) { Destroy(generatedObjects[i]); } generatedObjects.Clear(); } private void GenerateScale() { characters = CharacterController.I.characters; prizes = PrizeSerializer.GetPrizes(); generatedObjects = new(); GenerateIcons(); GeneratePoints(); GenerateLinks(); GenerateNumbers(); GenerateSubpoints(); GenerateInstructions(); } private void GenerateIcons() { generatedIcons = new(); for (int i = 0; i < characters.Length; i++) { RectTransform icon = Instantiate(IconTemplate, ScaleContainer).GetComponent(); icon.sizeDelta = new Vector2(IconSize, IconSize); icon.anchoredPosition = new Vector2(IconSize / 2, -IconSize / 2 - IconSize * i); icon.GetComponent().sprite = characters[i].IconSmall; generatedObjects.Add(icon.gameObject); generatedIcons.Add(icon); } } private void GeneratePoints() { List positions = new(); //собираем список точек куда спавнить кружки foreach (RectTransform icon in generatedIcons) { positions.Add((Vector2)icon.localPosition + Vector2.right * PointOffsetX); } // generatedPoints = new(); foreach (Vector2 position in positions) { RectTransform point = Instantiate(IconTemplate, ScaleContainer).GetComponent(); point.sizeDelta = new Vector2(PointSize, PointSize); point.localPosition = position; Image image = point.GetComponent(); image.sprite = circle; image.color = ScaleColor; generatedObjects.Add(point.gameObject); generatedPoints.Add(point); } } private void GenerateLinks() { generatedLinks = new(); List LinkPositions = new(); //собираем точки for (int i = 0; i < generatedPoints.Count - 1; i++) { float y = (generatedPoints[i].transform.localPosition.y + generatedPoints[i + 1].transform.localPosition.y) / 2; LinkPositions.Add(new Vector2(generatedPoints[0].localPosition.x, y)); } //последний уникальный LinkPositions.Add(new Vector2(generatedPoints[^1].localPosition.x, generatedPoints[^1].transform.localPosition.y)); foreach (Vector2 position in LinkPositions) { RectTransform link = Instantiate(IconTemplate, ScaleContainer).GetComponent(); link.sizeDelta = new Vector2(LinkWidth, IconSize); link.localPosition = position; Image image = link.GetComponent(); image.sprite = square; image.color = ScaleColor; generatedObjects.Add(link.gameObject); generatedLinks.Add(link); } } private void GenerateNumbers() { int i = 1; foreach (RectTransform point in generatedPoints) { TextMeshProUGUI label = Instantiate(PointNumberTemplate, ScaleContainer).GetComponent(); label.text = i.ToString(); label.transform.localPosition = point.localPosition; generatedObjects.Add(label.gameObject); i++; } } private void GenerateSubpoints() { generatedSubpoints = new List(); List positions = new List(); foreach (RectTransform point in generatedPoints) { positions.Add((Vector2)point.localPosition + Vector2.down * IconSize / 2); } int index = 0; foreach (Vector2 position in positions) { RectTransform subpoint = Instantiate(IconTemplate, ScaleContainer).GetComponent(); subpoint.localPosition = position; subpoint.sizeDelta = Vector2.one * SubpointSize; Image image = subpoint.GetComponent(); image.sprite = circle; bool prizedIndex = prizes[index].PrizeType != PrizeType.None; Color color = prizedIndex ? ScaleColorHighlighted : ScaleColor; image.color = color; if (prizedIndex) GeneratePrizeView(position, prizes[index]); generatedObjects.Add(subpoint.gameObject); generatedSubpoints.Add(subpoint); index++; } } private void GeneratePrizeView(Vector2 startPoint, Prize prize) { int strokeAmount = 5; int offsetX = 15; //генерация штрихов for (int i = 0; i < strokeAmount; i++) { RectTransform stroke = Instantiate(IconTemplate, ScaleContainer).GetComponent(); float x = startPoint.x + offsetX + StrokeWidth / 2 + (StrokeGap + StrokeWidth) * i; float y = startPoint.y; Vector2 position = new Vector2(x, y); stroke.localPosition = position; stroke.sizeDelta = new Vector2(StrokeWidth, LinkWidth); Image image = stroke.GetComponent(); image.sprite = square; image.color = ScaleColor; generatedObjects.Add(stroke.gameObject); } //генерация текста Vector2 lastStrokePosition = new Vector2(x: startPoint.x + offsetX + StrokeWidth / 2 + (StrokeGap + StrokeWidth) * (strokeAmount - 1), y: startPoint.y); TextMeshProUGUI label = Instantiate(PointNumberTemplate, ScaleContainer).GetComponent(); label.fontSize = prizetextFontsize; label.alignment = TextAlignmentOptions.MidlineLeft; string prizeText = GetPrizeText(prize); label.text = prizeText; float prizetextWidth = label.GetPreferredValues(prizeText).x; RectTransform rect = label.GetComponent(); Vector2 labelPosition = new Vector2(x: lastStrokePosition.x + StrokeWidth / 2 + StrokeGap + prizetextWidth / 2, y: lastStrokePosition.y); rect.localPosition = labelPosition; rect.sizeDelta = new Vector2(prizetextWidth, IconSize); generatedObjects.Add(label.gameObject); //генерация картинки подарка Vector2 giftPosition = labelPosition + Vector2.right * (IconSize + prizetextWidth) / 2; RectTransform gift = Instantiate(IconTemplate, ScaleContainer).GetComponent(); gift.localPosition = giftPosition; gift.sizeDelta = Vector2.one * IconSize; gift.GetComponent().sprite = giftSprite; generatedObjects.Add(gift.gameObject); } private void GenerateInstructions() { //заполняем призы которые надо проинструктировать List prizesWeHave = new(); foreach (var prize in prizes) { bool unique = !prizesWeHave.Contains(prize); bool notEmpty = prize.PrizeType != PrizeType.None; if (unique && notEmpty) prizesWeHave.Add(prize); } if (prizesWeHave.Count == 0) return; float blockWidth = InstructionContainer.sizeDelta.x; float blockHeight = InstructionContainer.sizeDelta.y / prizesWeHave.Count; for (int i = 0; i < prizesWeHave.Count; i++) { RectTransform block = Instantiate(PointNumberTemplate, InstructionContainer).GetComponent(); TextMeshProUGUI label = block.GetComponent(); Vector2 anchor = new Vector2(0, 1); block.anchorMin = anchor; block.anchorMax = anchor; block.pivot = anchor; block.sizeDelta = new Vector2(blockWidth, blockHeight); block.anchoredPosition = new Vector2(0, -blockHeight * i); label.text = GetPrizeInstruction(prizesWeHave[i]); label.alignment = TextAlignmentOptions.TopLeft; label.fontSize = instructionFontsize; generatedObjects.Add(block.gameObject); } } private string GetPrizeText(Prize prize) { string text = ""; if (prize.PrizeType == PrizeType.Marbles || prize.PrizeType == PrizeType.Ticket) { text = prize.Amount + " "; } text += prize.PrizeType switch { PrizeType.Hopper => "приз", PrizeType.Hopper2 => "приз", PrizeType.Ticket => "билет", PrizeType.Special => "суперприз", PrizeType.Marbles => "марблс", _ => "Без приза" }; return text; } private string GetPrizeInstruction(Prize prize) { string HopperInstruction = "Приз
Заберите маленький приз в окошке выдачи"; string TicketInstruction = "Билет
Заберите билеты в окошке выдачи"; string SpecialInstruction = "Суперприз
Чтобы выиграть главный суперприз нужно победить всех соперников. Если вы прошли все уровни, отсканируйте qr-код (он появится после победы) и свяжитесь с администратором для получения приза. Обязательно сфотографируйте победный экран!"; string MarblesInstruction = "Марблс
Заберите марблс в окошке выдачи"; return prize.PrizeType switch { PrizeType.Hopper => HopperInstruction, PrizeType.Hopper2 => HopperInstruction, PrizeType.Ticket => TicketInstruction, PrizeType.Special => SpecialInstruction, PrizeType.Marbles => MarblesInstruction, _ => "Что-то не так" }; } }