70 lines
2.2 KiB
C#
70 lines
2.2 KiB
C#
using UnityEngine;
|
||
using UnityEngine.EventSystems;
|
||
using UnityEngine.UI;
|
||
|
||
namespace Vanguard.UI
|
||
{
|
||
/// <summary>
|
||
/// ScrollRect с плавным колесом: колесо задаёт целевую позицию, а контент
|
||
/// подъезжает к ней за несколько кадров. Перетаскивание работает как обычно.
|
||
/// </summary>
|
||
public sealed class SmoothScrollRect : ScrollRect
|
||
{
|
||
public float WheelStep = 140f;
|
||
public float Smoothing = 0.06f;
|
||
|
||
private float _target;
|
||
private bool _smooth;
|
||
|
||
public override void OnScroll(PointerEventData eventData)
|
||
{
|
||
if (!vertical || content == null || viewport == null)
|
||
{
|
||
base.OnScroll(eventData);
|
||
return;
|
||
}
|
||
|
||
if (!_smooth)
|
||
_target = content.anchoredPosition.y;
|
||
|
||
var direction = Mathf.Sign(eventData.scrollDelta.y);
|
||
if (Mathf.Approximately(direction, 0f))
|
||
return;
|
||
|
||
var max = Mathf.Max(0f, content.rect.height - viewport.rect.height);
|
||
_target = Mathf.Clamp(_target - direction * WheelStep, 0f, max);
|
||
velocity = Vector2.zero;
|
||
_smooth = true;
|
||
}
|
||
|
||
public override void OnBeginDrag(PointerEventData eventData)
|
||
{
|
||
_smooth = false;
|
||
base.OnBeginDrag(eventData);
|
||
}
|
||
|
||
protected override void LateUpdate()
|
||
{
|
||
if (!_smooth || content == null || viewport == null)
|
||
{
|
||
base.LateUpdate();
|
||
return;
|
||
}
|
||
|
||
var position = content.anchoredPosition;
|
||
var max = Mathf.Max(0f, content.rect.height - viewport.rect.height);
|
||
_target = Mathf.Clamp(_target, 0f, max);
|
||
|
||
var t = 1f - Mathf.Exp(-Time.unscaledDeltaTime / Mathf.Max(0.01f, Smoothing));
|
||
var next = Mathf.Lerp(position.y, _target, t);
|
||
if (Mathf.Abs(next - _target) < 0.5f)
|
||
{
|
||
next = _target;
|
||
_smooth = false;
|
||
}
|
||
|
||
content.anchoredPosition = new Vector2(position.x, next);
|
||
}
|
||
}
|
||
}
|