client: плавный скролл и колесо над картами
CI / test (push) Successful in 3m12s Details

- SmoothScrollRect (UiKit): колесо задаёт целевую позицию, контент
  плавно подъезжает; протяжка работает как раньше. Подключён ко всем
  прокруткам.
- Правый клик по карте заменён с EventTrigger на RightClickRelay
  (только IPointerClickHandler), из-за чего EventTrigger раньше съедал
  колесо и скролл работал только между картами.
- Проверки: EditMode 69/69, standalone собран.
This commit is contained in:
MpakobecEx 2026-11-01 19:20:51 +05:00
parent 2ab7eead52
commit ce687b60da
6 changed files with 94 additions and 14 deletions

View File

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using Vanguard.Api;
using Vanguard.Api.Contracts;
@ -1442,18 +1441,9 @@ namespace Vanguard.UI
private void AddRightClick(GameObject target, string printingId, CardCatalogItemDto meta)
{
var trigger = target.GetComponent<EventTrigger>()
?? target.AddComponent<EventTrigger>();
var entry = new EventTrigger.Entry { eventID = EventTriggerType.PointerClick };
entry.callback.AddListener(data =>
{
if (data is PointerEventData pointer
&& pointer.button == PointerEventData.InputButton.Right)
{
ShowCardOverlay(printingId, meta);
}
});
trigger.triggers.Add(entry);
var relay = target.GetComponent<RightClickRelay>()
?? target.AddComponent<RightClickRelay>();
relay.Clicked = _ => ShowCardOverlay(printingId, meta);
}
private void ShowCardOverlay(string printingId, CardCatalogItemDto meta)

View File

@ -0,0 +1,21 @@
using System;
using UnityEngine;
using UnityEngine.EventSystems;
namespace Vanguard.UI
{
/// <summary>
/// Правый клик по объекту. В отличие от EventTrigger реализует только
/// IPointerClickHandler, поэтому колесо мыши проходит к ScrollRect.
/// </summary>
public sealed class RightClickRelay : MonoBehaviour, IPointerClickHandler
{
public Action<PointerEventData> Clicked;
public void OnPointerClick(PointerEventData eventData)
{
if (eventData != null && eventData.button == PointerEventData.InputButton.Right)
Clicked?.Invoke(eventData);
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a549a5f7e2587444caecfdb1d3abbc0a

View File

@ -0,0 +1,65 @@
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 max = Mathf.Max(0f, content.rect.height - viewport.rect.height);
_target = Mathf.Clamp(_target + eventData.scrollDelta.y * WheelStep, -max, 0f);
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, -max, 0f);
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);
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: baf08a955c0310444bf2c36f2ffa644c

View File

@ -370,7 +370,7 @@ namespace Vanguard.UI
name,
typeof(RectTransform),
typeof(Image),
typeof(ScrollRect));
typeof(SmoothScrollRect));
var rect = (RectTransform)root.transform;
rect.SetParent(parent, false);
Stretch(rect);