346 lines
12 KiB
C#
346 lines
12 KiB
C#
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using TMPro;
|
||
using PrizeSystem;
|
||
|
||
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<Prize> prizes;
|
||
List<GameObject> generatedObjects;
|
||
List<RectTransform> generatedIcons;
|
||
List<RectTransform> generatedPoints;
|
||
List<RectTransform> generatedLinks;
|
||
List<RectTransform> 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.LoadPrizes();
|
||
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<RectTransform>();
|
||
icon.sizeDelta = new Vector2(IconSize, IconSize);
|
||
icon.anchoredPosition = new Vector2(IconSize / 2, -IconSize / 2 - IconSize * i);
|
||
|
||
icon.GetComponent<Image>().sprite = characters[i].IconSmall;
|
||
|
||
generatedObjects.Add(icon.gameObject);
|
||
generatedIcons.Add(icon);
|
||
|
||
}
|
||
}
|
||
|
||
private void GeneratePoints()
|
||
{
|
||
List<Vector2> 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<RectTransform>();
|
||
point.sizeDelta = new Vector2(PointSize, PointSize);
|
||
point.localPosition = position;
|
||
|
||
Image image = point.GetComponent<Image>();
|
||
image.sprite = circle;
|
||
image.color = ScaleColor;
|
||
|
||
generatedObjects.Add(point.gameObject);
|
||
generatedPoints.Add(point);
|
||
}
|
||
}
|
||
|
||
|
||
private void GenerateLinks()
|
||
{
|
||
generatedLinks = new();
|
||
List<Vector2> 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<RectTransform>();
|
||
link.sizeDelta = new Vector2(LinkWidth, IconSize);
|
||
link.localPosition = position;
|
||
Image image = link.GetComponent<Image>();
|
||
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<TextMeshProUGUI>();
|
||
label.text = i.ToString();
|
||
label.transform.localPosition = point.localPosition;
|
||
|
||
generatedObjects.Add(label.gameObject);
|
||
i++;
|
||
}
|
||
}
|
||
|
||
private void GenerateSubpoints()
|
||
{
|
||
generatedSubpoints = new List<RectTransform>();
|
||
List<Vector2> positions = new List<Vector2>();
|
||
|
||
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<RectTransform>();
|
||
subpoint.localPosition = position;
|
||
subpoint.sizeDelta = Vector2.one * SubpointSize;
|
||
|
||
Image image = subpoint.GetComponent<Image>();
|
||
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<RectTransform>();
|
||
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>();
|
||
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<TextMeshProUGUI>();
|
||
label.fontSize = prizetextFontsize;
|
||
label.alignment = TextAlignmentOptions.MidlineLeft;
|
||
string prizeText = GetPrizeText(prize);
|
||
label.text = prizeText;
|
||
float prizetextWidth = label.GetPreferredValues(prizeText).x;
|
||
|
||
RectTransform rect = label.GetComponent<RectTransform>();
|
||
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<RectTransform>();
|
||
gift.localPosition = giftPosition;
|
||
gift.sizeDelta = Vector2.one * IconSize;
|
||
gift.GetComponent<Image>().sprite = giftSprite;
|
||
|
||
generatedObjects.Add(gift.gameObject);
|
||
|
||
}
|
||
|
||
private void GenerateInstructions()
|
||
{
|
||
|
||
//заполняем призы которые надо проинструктировать
|
||
List<Prize> 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<RectTransform>();
|
||
TextMeshProUGUI label = block.GetComponent<TextMeshProUGUI>();
|
||
|
||
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 is CountablePrize cp)
|
||
{
|
||
if (cp.PrizeType == PrizeType.Marbles || cp.PrizeType == PrizeType.Ticket)
|
||
{
|
||
text = cp.Amount + " ";
|
||
}
|
||
|
||
text += cp.PrizeType switch
|
||
{
|
||
PrizeType.Hopper => "приз",
|
||
PrizeType.Hopper2 => "приз",
|
||
PrizeType.Ticket => "билет",
|
||
PrizeType.Marbles => "марблс",
|
||
_ => "Без приза"
|
||
};
|
||
|
||
}
|
||
|
||
return text;
|
||
}
|
||
|
||
|
||
private string GetPrizeInstruction(Prize prize)
|
||
{
|
||
string HopperInstruction = "<b>Приз</b><br>Заберите маленький приз в окошке выдачи";
|
||
string TicketInstruction = "<b>Билет</b><br>Заберите билеты в окошке выдачи";
|
||
string SpecialInstruction = "<b>Суперприз</b><br>Чтобы выиграть главный суперприз нужно победить всех соперников. Если вы прошли все уровни, отсканируйте qr-код (он появится после победы) и свяжитесь с администратором для получения приза. Обязательно сфотографируйте победный экран!";
|
||
string MarblesInstruction = "<b>Марблс</b><br>Заберите марблс в окошке выдачи";
|
||
|
||
return prize.PrizeType switch
|
||
{
|
||
PrizeType.Hopper => HopperInstruction,
|
||
PrizeType.Hopper2 => HopperInstruction,
|
||
PrizeType.Ticket => TicketInstruction,
|
||
PrizeType.Qr => SpecialInstruction,
|
||
PrizeType.Marbles => MarblesInstruction,
|
||
_ => "Что-то не так"
|
||
};
|
||
}
|
||
|
||
}
|