178 lines
5.0 KiB
C#
178 lines
5.0 KiB
C#
using System.Collections;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
public class IntView : MonoBehaviour, ISettingView
|
|
{
|
|
[Header("Layout ссылки")]
|
|
[SerializeField] private TextMeshProUGUI ValueLabel;
|
|
[SerializeField] private GameObject LeftArrow;
|
|
[SerializeField] private GameObject RightArrow;
|
|
|
|
[Header("Ускоренное переключение")]
|
|
[SerializeField] private float initialDelay = 0.5f; // Задержка перед началом ускорения
|
|
[SerializeField] private float minRepeatDelay = 0.05f; // Минимальная задержка между изменениями
|
|
[SerializeField] private float accelerationSpeed = 0.95f; // Скорость ускорения (чем меньше, тем быстрее)
|
|
|
|
[Header("Звук")]
|
|
[SerializeField] private bool UseSound = true;
|
|
[SerializeField] private AudioClip SwitchClip;
|
|
[SerializeField] private AudioSource Source;
|
|
|
|
// Кэш значений настройки
|
|
private int minValue;
|
|
private int maxValue;
|
|
private int currentValue;
|
|
private int step = 1;
|
|
|
|
// Состояние ускоренного переключения
|
|
private Coroutine accelerationCoroutine;
|
|
private int currentDirection = 0; // -1 = влево, 0 = нет, 1 = вправо
|
|
|
|
public Setting CachedSetting { get; private set; }
|
|
|
|
public void Initialize(Setting setting)
|
|
{
|
|
CachedSetting = setting;
|
|
CacheSettingValues(setting);
|
|
|
|
if (Source != null && SwitchClip != null)
|
|
Source.clip = SwitchClip;
|
|
|
|
UpdateUI();
|
|
}
|
|
|
|
public void TakeInput(int direction)
|
|
{
|
|
if (direction != 0)
|
|
{
|
|
if (currentDirection == direction)
|
|
return;
|
|
|
|
currentDirection = direction;
|
|
ChangeValue(currentDirection);
|
|
|
|
if (accelerationCoroutine != null)
|
|
StopCoroutine(accelerationCoroutine);
|
|
accelerationCoroutine = StartCoroutine(AcceleratedSwitching());
|
|
}
|
|
else
|
|
{
|
|
|
|
if (accelerationCoroutine != null)
|
|
{
|
|
StopCoroutine(accelerationCoroutine);
|
|
accelerationCoroutine = null;
|
|
}
|
|
currentDirection = 0;
|
|
|
|
if (UseSound && Source != null && Source.isPlaying)
|
|
Source.Stop();
|
|
}
|
|
}
|
|
|
|
private IEnumerator AcceleratedSwitching()
|
|
{
|
|
float delay = initialDelay;
|
|
yield return new WaitForSeconds(delay);
|
|
|
|
// Ускоренное переключение
|
|
while (currentDirection != 0)
|
|
{
|
|
ChangeValue(currentDirection);
|
|
delay = Mathf.Max(minRepeatDelay, delay * accelerationSpeed);
|
|
|
|
yield return new WaitForSeconds(delay);
|
|
}
|
|
}
|
|
|
|
private void ChangeValue(int direction)
|
|
{
|
|
if (direction == 0) return;
|
|
|
|
int newValue = currentValue + step * (int)Mathf.Sign(direction);
|
|
|
|
newValue = Mathf.Clamp(newValue, minValue, maxValue);
|
|
if (newValue == currentValue)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentValue = newValue;
|
|
CachedSetting.IntValue = currentValue;
|
|
|
|
|
|
if (UseSound)
|
|
PlaySound();
|
|
|
|
UpdateUI();
|
|
}
|
|
|
|
private void UpdateUI()
|
|
{
|
|
if (ValueLabel != null)
|
|
ValueLabel.text = currentValue.ToString();
|
|
UpdateArrows();
|
|
}
|
|
|
|
private void UpdateArrows()
|
|
{
|
|
LeftArrow.SetActive(currentValue > minValue);
|
|
RightArrow.SetActive(currentValue < maxValue);
|
|
}
|
|
|
|
|
|
|
|
|
|
private void PlaySound()
|
|
{
|
|
if (!UseSound || Source == null) return;
|
|
|
|
// Динамический питч в зависимости от скорости переключения
|
|
if (accelerationCoroutine != null)
|
|
{
|
|
// При ускоренном переключении повышаем питч
|
|
float pitchMultiplier = Mathf.Lerp(1f, 2f,
|
|
(initialDelay - Mathf.Max(minRepeatDelay,
|
|
initialDelay * Mathf.Pow(accelerationSpeed, 10))) / initialDelay);
|
|
Source.pitch = Mathf.Clamp(0.8f + pitchMultiplier * 0.5f, 0.8f, 1.5f);
|
|
}
|
|
else
|
|
{
|
|
Source.pitch = 1f;
|
|
}
|
|
|
|
Source.PlayOneShot(SwitchClip);
|
|
}
|
|
|
|
private void CacheSettingValues(Setting setting)
|
|
{
|
|
minValue = setting.IntMin;
|
|
maxValue = setting.IntMax;
|
|
currentValue = setting.IntValue;
|
|
step = setting.IntStep;
|
|
|
|
if (step <= 0)
|
|
{
|
|
Debug.LogWarning($"Step is zero or negative ({step}), setting to 1", this);
|
|
step = 1;
|
|
}
|
|
|
|
if (minValue >= maxValue)
|
|
{
|
|
Debug.LogWarning($"Invalid range: min={minValue}, max={maxValue}", this);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (accelerationCoroutine != null)
|
|
StopCoroutine(accelerationCoroutine);
|
|
|
|
if (Source != null && Source.isPlaying)
|
|
Source.Stop();
|
|
}
|
|
} |