선택된 ui 자동 트래킹

This commit is contained in:
NTG_Lenovo 2025-08-06 13:22:30 +09:00
parent 94ec8f8db3
commit cc8e079797
3 changed files with 118 additions and 2 deletions

View File

@ -6,15 +6,16 @@
namespace DDD
{
public class ItemSlotUi : MonoBehaviour, ISelectHandler
public class ItemSlotUi : MonoBehaviour, ISelectHandler, IAutoScrollItem
{
[field: SerializeField] public RectTransform RectTransform { get; private set; }
[SerializeField] private Button _button;
[SerializeField] private Image _backgroundImage;
[SerializeField] private Image _icon;
[SerializeField] private TextMeshProUGUI _countText;
[SerializeField] private Image _markImage;
[SerializeField] private Animator _animator;
[field: SerializeField] public ItemViewModel Model { get; private set; }
public IItemSlotUiStrategy Strategy { get; private set; }

View File

@ -0,0 +1,106 @@
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace DDD
{
public class AutoScrollToSelected : MonoBehaviour
{
private ScrollRect _scrollRect;
private RectTransform _viewport;
private RectTransform _content;
private GameObject _lastSelected;
private bool _wasScrolling;
private void Awake()
{
_scrollRect = GetComponent<ScrollRect>();
_viewport = _scrollRect.viewport;
_content = _scrollRect.content;
}
private void Update()
{
if (_scrollRect.velocity.sqrMagnitude > 0.01f)
{
_wasScrolling = true;
return;
}
if (_wasScrolling)
{
_wasScrolling = false;
return;
}
var selected = EventSystem.current.currentSelectedGameObject;
if (selected == null || selected == _lastSelected) return;
_lastSelected = selected;
if (!selected.TryGetComponent<IAutoScrollItem>(out var autoScrollItem)) return;
var target = autoScrollItem.RectTransform;
if (!target.IsChildOf(_content)) return;
if (!IsFullyVisible(target))
{
ScrollToMakeFullyVisible(target);
}
}
private bool IsFullyVisible(RectTransform target)
{
var worldCorners = new Vector3[4];
target.GetWorldCorners(worldCorners);
for (int i = 0; i < 4; i++)
{
Vector3 local = _viewport.InverseTransformPoint(worldCorners[i]);
if (!_viewport.rect.Contains(local)) return false;
}
return true;
}
private void ScrollToMakeFullyVisible(RectTransform target)
{
Canvas.ForceUpdateCanvases();
float scrollRange = _content.rect.height - _viewport.rect.height;
if (scrollRange <= 0f) return;
Vector3[] itemCorners = new Vector3[4];
target.GetWorldCorners(itemCorners);
Vector3[] viewportCorners = new Vector3[4];
_viewport.GetWorldCorners(viewportCorners);
float itemTop = itemCorners[1].y;
float itemBottom = itemCorners[0].y;
float viewTop = viewportCorners[1].y;
float viewBottom = viewportCorners[0].y;
float offset = 0f;
float normalizedDelta = 0f;
if (itemTop > viewTop)
{
offset = itemTop - viewTop;
normalizedDelta = offset / scrollRange;
_scrollRect.verticalNormalizedPosition += normalizedDelta;
}
else if (itemBottom < viewBottom)
{
offset = viewBottom - itemBottom;
normalizedDelta = offset / scrollRange;
_scrollRect.verticalNormalizedPosition -= normalizedDelta;
}
else
{
return;
}
_scrollRect.verticalNormalizedPosition = Mathf.Clamp01(_scrollRect.verticalNormalizedPosition);
}
}
}

View File

@ -0,0 +1,9 @@
using UnityEngine;
namespace DDD
{
public interface IAutoScrollItem
{
RectTransform RectTransform { get; }
}
}