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(); rect.anchoredPosition = new Vector2(XPosition, 0); XPosition += blockWidth; TextMeshProUGUI label = rect.GetComponent(); 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; } } } }