125 lines
3.5 KiB
C#
125 lines
3.5 KiB
C#
using TMPro;
|
||
using UnityEngine;
|
||
|
||
public class StringView : MonoBehaviour, ISettingView
|
||
{
|
||
[Header("Настройки Layout'а")]
|
||
[SerializeField] private RectTransform Content;
|
||
[SerializeField] private float blockWidth = 150f;
|
||
[SerializeField] private GameObject LeftPointer;
|
||
[SerializeField] private GameObject RightPointer;
|
||
|
||
[Header("Звуки")]
|
||
[SerializeField] private AudioClip SwitchClip;
|
||
|
||
[Header("Префабы")]
|
||
[SerializeField] private GameObject TextSlotPrefab;
|
||
|
||
public SettingDTO CachedSetting { get; private set; }
|
||
private int MaxIndex => CachedSetting.AllowedValues.Count - 1;
|
||
private float ContentXPosition => Content.anchoredPosition.x;
|
||
|
||
private float targetXPosition;
|
||
private float velocityX = 0;
|
||
private int currentIndex = 0;
|
||
private bool canMove = true;
|
||
private bool needAnimation = false;
|
||
|
||
public void Initialize(SettingDTO setting)
|
||
{
|
||
CachedSetting = setting;
|
||
currentIndex = CalculateCurrentIndex();
|
||
|
||
GenerateLine();
|
||
}
|
||
|
||
public void TakeInput(int direction)
|
||
{
|
||
//Сброс блока на движение
|
||
if (direction == 0)
|
||
{
|
||
canMove = true;
|
||
return;
|
||
}
|
||
|
||
if (!canMove) return;
|
||
|
||
int newIndex = Mathf.Clamp(currentIndex + direction, 0, MaxIndex);
|
||
if (newIndex == currentIndex) return;
|
||
|
||
currentIndex = newIndex;
|
||
|
||
//upd setting
|
||
CachedSetting.StringValue = CachedSetting.AllowedValues[currentIndex];
|
||
targetXPosition = -currentIndex * blockWidth;
|
||
needAnimation = true;
|
||
SoundManager.PlayUi(SwitchClip);
|
||
|
||
UpdatePointers();
|
||
|
||
canMove = false;
|
||
}
|
||
|
||
private int CalculateCurrentIndex()
|
||
{
|
||
int index = CachedSetting.AllowedValues.IndexOf(CachedSetting.StringValue);
|
||
return index < 0 ? 0 : index;
|
||
}
|
||
|
||
private void OnDisable()
|
||
{
|
||
StopAllCoroutines();
|
||
}
|
||
|
||
private void UpdatePointers()
|
||
{
|
||
LeftPointer.SetActive(currentIndex > 0);
|
||
RightPointer.SetActive(currentIndex < MaxIndex);
|
||
}
|
||
|
||
private void GenerateLine()
|
||
{
|
||
ClearContent();
|
||
float XPosition = 0;
|
||
foreach (string text in CachedSetting.AllowedValues)
|
||
{
|
||
RectTransform rect = Instantiate(TextSlotPrefab, Content).GetComponent<RectTransform>();
|
||
rect.anchoredPosition = new Vector2(XPosition, 0);
|
||
XPosition += blockWidth;
|
||
|
||
TextMeshProUGUI label = rect.GetComponent<TextMeshProUGUI>();
|
||
label.text = text;
|
||
}
|
||
|
||
//переместиться на текущее значение
|
||
targetXPosition = -currentIndex * blockWidth;
|
||
UpdatePointers();
|
||
}
|
||
|
||
private void ClearContent()
|
||
{
|
||
foreach (Transform child in Content)
|
||
Destroy(child.gameObject);
|
||
}
|
||
|
||
private void Update()
|
||
{
|
||
if (needAnimation)
|
||
{
|
||
float smoothedX = Mathf.SmoothDamp(current: ContentXPosition,
|
||
target: targetXPosition,
|
||
currentVelocity: ref velocityX,
|
||
smoothTime: 0.1f);
|
||
Content.anchoredPosition = new Vector2(smoothedX, Content.anchoredPosition.y);
|
||
|
||
//Дошли до целевой точки
|
||
if (Mathf.Approximately(ContentXPosition, targetXPosition))
|
||
{
|
||
needAnimation = false;
|
||
canMove = true;
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|