chip-game/Assets/Scripts/CharacterSettingPanel.cs
2026-01-12 09:36:17 +03:00

290 lines
8.7 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class CharacterSettingPanel : MonoBehaviour
{
[SerializeField] TextMeshProUGUI nameLabel;
[SerializeField] TextMeshProUGUI PrizeTypeLabel;
[SerializeField] TextMeshProUGUI AmountLabel;
[SerializeField] Image CharacterIcon;
[SerializeField] Image ConfirmIcon;
[SerializeField] RectTransform pointer;
[SerializeField] List<Vector2> pointerPositions = new List<Vector2>() { };
[SerializeField] List<Graphic> fadeGraphics;
[SerializeField] float fadeTime = 0.5f;
private Coroutine fadeInCoroutine;
private Coroutine fadeOutCoroutine;
Character[] characters;
int botsAmount;
List<Prize> prizes;
int direction1; //джойстик 1 выбор настройки
int direction2; //джойстик 2 выбор опции внутир настройки
int direction3; //p1 | p2 переключение персонажа
bool holdingSave; //держим p1 + p2
float timeToConfirm = 3;
float timeRest;
int characterIndex = 0;
int prizeTypeIndex;
int prizeAmount;
int setting = 0; // что сейчас настраивается. 0 - тип приза, 1 - количество призов
Array PrizeTypes = Enum.GetValues(typeof(PrizeType));
private void OnEnable() => Initialize();
private void Update()
{
collectInputs();
SwitchSetting(direction1);
SwitchOption(direction2);
SwitchCharacter(direction3);
SaveProcess(holdingSave);
}
void Initialize()
{
prizes = PrizeSerializer.GetPrizes();
characters = CharacterController.I.characters;
botsAmount = GameManager.instance.botsAmount;
timeRest = timeToConfirm;
characterIndex = 0;
SetCharacter(characterIndex);
}
void SetCharacter(int index)
{
Character characterToSet = characters[index];
Prize prizeToSet = prizes[index];
nameLabel.text = characterToSet.Name;
PrizeTypeLabel.text = PrizeTypeToString(prizeToSet.PrizeType);
prizeAmount = ValidatePrizeAmount(prizeToSet.Amount, prizeToSet.PrizeType);
prizeToSet.Amount = prizeAmount;
AmountLabel.text = prizeToSet.Amount.ToString();
CharacterIcon.sprite = characterToSet.Icon;
prizeTypeIndex = Array.IndexOf(PrizeTypes, prizeToSet.PrizeType);
setting = 0;
pointer.anchoredPosition = pointerPositions[setting];
}
void collectInputs()
{
direction1 = 0;
direction1 += In.GetButtonDown(ButtonPinMapping.left1) ? -1 : 0;
direction1 += In.GetButtonDown(ButtonPinMapping.right1) ? +1 : 0;
direction2 = 0;
direction2 += In.GetButtonDown(ButtonPinMapping.left2) ? -1 : 0;
direction2 += In.GetButtonDown(ButtonPinMapping.right2) ? +1 : 0;
direction3 = 0;
direction3 += In.GetButtonDown(ButtonPinMapping.startOnePlayer) ? -1 : 0;
direction3 += In.GetButtonDown(ButtonPinMapping.startTwoPlayers) ? +1 : 0;
//holdingSave = In.GetButton(ButtonPinMapping.startOnePlayer) && In.GetButton(ButtonPinMapping.startTwoPlayers);
//holdingSave = In.GetButton(ButtonPinMapping.down2);
holdingSave = In.GetButton(ButtonPinMapping.startOnePlayer) && In.GetButton(ButtonPinMapping.startTwoPlayers);
}
//перекл между настройками (тип -> колво)
void SwitchSetting(int direction)
{
if (direction == 0) return;
if (direction == -1)
{
setting = 0;
}
if (direction == 1)
{
setting = 1;
}
pointer.anchoredPosition = pointerPositions[setting];
}
//перекл между опциями внутри настройки
void SwitchOption(int direction)//тут будем записываться
{
if (direction == 0) return;
if (setting == 0)//меняем тип
{
prizeTypeIndex = (prizeTypeIndex + direction + PrizeTypes.Length) % PrizeTypes.Length;
PrizeType prizeTypeToSet = (PrizeType)PrizeTypes.GetValue(prizeTypeIndex);
//validation: отсечь спец приз всем кроме последнего
if (characterIndex != botsAmount-1 && prizeTypeToSet == PrizeType.Special)
{
prizeTypeIndex = (prizeTypeIndex + direction + PrizeTypes.Length) % PrizeTypes.Length;
prizeTypeToSet = (PrizeType)PrizeTypes.GetValue(prizeTypeIndex);
}
PrizeTypeLabel.text = PrizeTypeToString(prizeTypeToSet);
prizes[characterIndex].PrizeType = prizeTypeToSet;
prizeAmount = ValidatePrizeAmount(prizeAmount, prizes[characterIndex].PrizeType);
AmountLabel.text = prizeAmount.ToString();
prizes[characterIndex].Amount = prizeAmount;
}
if (setting == 1)//меняем количество
{
prizeAmount += direction;
prizeAmount = ValidatePrizeAmount(prizeAmount, prizes[characterIndex].PrizeType);
prizes[characterIndex].Amount = prizeAmount;
AmountLabel.text = prizeAmount.ToString();
}
}
int ValidatePrizeAmount(int amount, PrizeType prizeType)
{
if (prizeType == PrizeType.None)
{
return 0;
}
if (prizeType == PrizeType.Hopper)
{
return Mathf.Clamp(amount, 1, 5);
}
if (prizeType == PrizeType.Special)
{
return 1;
}
if (prizeType == PrizeType.Ticket)
{
return Mathf.Clamp(amount, 1, 100);
}
if (prizeType == PrizeType.Marbles)
{
return Mathf.Clamp(amount, 1, 5);
}
return 0;
}
void SwitchCharacter(int direction)
{
if (direction == 0) { return; }
characterIndex = (characterIndex + direction + botsAmount) % botsAmount;
SetCharacter(characterIndex);
}
void SaveProcess(bool pressed)
{
HandleFadeAnimation(pressed);
HandleConfirmationTimer(pressed);
if (ShouldExecuteSave())
SaveAndClose();
}
private bool ShouldExecuteSave() =>
timeRest <= 0;
private void HandleConfirmationTimer(bool pressed)
{
timeRest += Time.deltaTime;
if (pressed) timeRest -= Time.deltaTime * 2;
timeRest = Mathf.Clamp(timeRest, 0, timeToConfirm);
ConfirmIcon.fillAmount = (timeToConfirm - timeRest) / timeToConfirm;
}
private void HandleFadeAnimation(bool pressed)
{
if (pressed)
{
if (fadeInCoroutine == null)
{
if (fadeOutCoroutine != null)
{
StopCoroutine(fadeOutCoroutine);
fadeOutCoroutine = null;
}
fadeInCoroutine = StartCoroutine(Fade(1));
}
}
else
{
if (Mathf.Approximately(timeRest, timeToConfirm) && fadeOutCoroutine == null)
{
if (fadeInCoroutine != null)
{
StopCoroutine(fadeInCoroutine);
fadeInCoroutine = null;
}
fadeOutCoroutine = StartCoroutine(Fade(-1));
}
}
}
private void SaveAndClose()
{
Debug.Log("Сохранение конфига персонажей");
PrizeSerializer.SetPrizes(prizes);
CharacterController.I.RefreshPrizes();
timeRest = timeToConfirm;
GameManager.instance.stateMachine.ChangeState(new SettingsState());
}
string PrizeTypeToString(PrizeType prizeType)
{
return prizeType switch
{
PrizeType.None => "Без приза",
PrizeType.Hopper => "Хоппер 1",
PrizeType.Hopper2 => "Хоппер 2",
PrizeType.Ticket => "Билет",
PrizeType.Special => "Суперприз",
PrizeType.Marbles => "Марблс",
_ => "Без приза"
};
}
IEnumerator Fade(int direction)
{
Vector4 color = fadeGraphics[0].color;
Vector4 targetColor = direction switch
{
-1 => new Vector4(1, 1, 1, 0),
1 => new Vector4(1, 1, 1, 1),
_ => new Vector4(1, 1, 1, 0)
};
while (color != targetColor)
{
color = Vector4.MoveTowards(color, targetColor, Time.deltaTime / fadeTime);
foreach (Graphic graphic in fadeGraphics)
{
graphic.color = color;
}
yield return null;
}
}
}